简体   繁体   中英

WPF(.NET-Core):How can I bind a buttons background color, to a matrix's indexed value progmatically?

In a WPF .NET-CORE application I want to bind the background color of each button in a dynamic grid to a matrix's indexed value. I can't seem to get it work, the buttons appear, but they dont have any color. Here is my code below:

XML

<Grid>
    <DockPanel >
        <Menu Height="24" DockPanel.Dock="Top">
            <MenuItem Name ="smallGameButton" Header="4x16" Click="NewGame"/>
            <MenuItem Name ="mediumGameButton" Header="8x16" Click="NewGame"/>
            <MenuItem Name ="largeGameButton" Header="12x16" Click="NewGame"/>
        </Menu>
        <Grid Name="GameTable"/>

    </DockPanel>

</Grid>

View: This is what the NewGame buttons do, the buttons perfectly appear, but have no color.

public void NewGame(object sender, RoutedEventArgs e)
    {
        string buttonName = (sender as MenuItem).Name;

        switch (buttonName)
        {
            case "smallGameButton":
                InitGame(4, 16);
                break;

            case "mediumGameButton":
                InitGame(8, 16);
                break;

            case "largeGameButton":
                InitGame(12, 16);
                break;
            default:
                break;
        }
    }

 private void InitGame(int width,int height)
    {
        //RESET GRID
        GameTable.ColumnDefinitions.Clear();
        GameTable.RowDefinitions.Clear();
        GameTable.Children.Clear();

        _viewModel = new GameTableViewModel(width,height);
        DataContext = _viewModel;

        Width =30*width + 20;
        Height = 30 * height + 70; 

        for(int i = 0; i < width; i++)
        {
            ColumnDefinition CDef = new ColumnDefinition();
            CDef.Width = new GridLength(30, GridUnitType.Pixel);

            GameTable.ColumnDefinitions.Add(CDef) ; 
        }
        for(int i = 0; i < height; i++)
        {
            RowDefinition RDef = new RowDefinition();
            RDef.Height = new GridLength(30, GridUnitType.Pixel);
            GameTable.RowDefinitions.Add(RDef);
        }

        for(int i = 0; i < height; i++)
        {
            for(int j = 0; j < width; j++)
            {
                Button button = new Button();
                Grid.SetRow(button, i);
                Grid.SetColumn(button, j);

                Binding b = new Binding("Matrix["+i.ToString()+","+j.ToString()+"]");
                b.Source = _viewModel;
                button.SetBinding(Button.BackgroundProperty, b);

                GameTable.Children.Add(button);
            }
        }
    }

ViewModel

class GameTableViewModel
{
    public Brush[,] Matrix;
    public Brush Color = Brushes.Red;
    public GameTableViewModel(int width,int height)
    {
        Matrix = new Brush[height, width];
        for(int i = 0; i < height; i++)
        {
            for(int j = 0; j < width; j++)
            {
                Matrix[i, j] = Brushes.Blue;
            }
        }
    }
}

Found it out...The notification about the changed property didn't happen.

Correct ViewModel:

class GameTableViewModel : ViewModelBase
{
    private Brush[,] _matrix;
    public Brush this[int height,int width] 
        { get=>_matrix[height,width];
        set
        {
            _matrix[height,width] = value;
            OnPropertyChanged();
        }
    }
    public Brush Color = Brushes.Red;
    public GameTableViewModel(int width,int height)
    {
        _matrix = new Brush[height, width];
        for(int i = 0; i < height; i++)
        {
            for(int j = 0; j < width; j++)
            {
                _matrix[i, j] = Brushes.Blue;
            }
        }
    }
}

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Binding in the View

Binding b = new Binding("["+i.ToString()+","+j.ToString()+"]");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM