Question

I currently have an object (Cell) set as a button's data context. The color of the button has to depend on a property belonging to that object (CellState); if the cell is ALIVE the background property of the Button that it's tied to is set to Black, and if the cell is DEAD the Button is White. I have to use a value converter to handle the visual representation of a cell's "state", so I have a ValueConverter that looks like this:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        SolidColorBrush b = null;
        State s = (State)value;
        if (s == State.ALIVE)
        {
            b = Brushes.Black;
        }
        else if (s == State.DEAD)
        {
            b = Brushes.White;
        }

        return b;
    }

I'm not sure how to properly bind the button's background property to the Cell's CellState property using the value converter. This is what I have so far:

Button b = new Button();
b.DataContext = new Cell();
b.Background = Brushes.White;
b.Click += StateChangeClick_Handler;

Binding binding = new Binding();

StateToBrushConverter stateConverter = new StateToBrushConverter();
binding.Converter = stateConverter;
Cell c = (Cell)b.DataContext;

binding.ConverterParameter = c.CellState;
b.SetBinding(Button.BackgroundProperty, binding);

cellGrid.Children.Add(b);

Any help would be greatly appreciated.

Was it helpful?

Solution

Here's the full source for an example that works - you basically need to make sure to implement INotifyPropertyChanged on the custom class whose property is being bound to the button. In my example I created a simple application with one button (the same one you already have) and a checkbox just so I can change the State property of the Cell object programmatically and see the background changing.

So here it is:

public partial class MainWindow : Window
{
    private Cell cell = new Cell();
    public MainWindow()
    {
        InitializeComponent();
        b.DataContext = cell;
        b.Background = Brushes.White;

        Binding binding = new Binding("CellState");
        StateToBrushConverter stateConverter = new StateToBrushConverter();
        binding.Converter = stateConverter;
        Cell c = (Cell)b.DataContext;

        binding.ConverterParameter = c.CellState;
        b.SetBinding(Button.BackgroundProperty, binding);
    }

    private void checkBox1_Checked(object sender, RoutedEventArgs e)
    {
        this.cell.CellState = (bool) checkBox1.IsChecked ? State.ALIVE : State.DEAD;
    }
}

public enum State { ALIVE, DEAD }

public class Cell : INotifyPropertyChanged
{
    private State state;
    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    public State CellState
    {
        get { return this.state; }
        set
        {
            if (value != this.state)
            {
                this.state = value;
                NotifyPropertyChanged("CellState");
            }
        }
    }
}

[ValueConversion(typeof(State), typeof(String))]
public class StateToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush b = null;
        State s = (State)value;
        if (s == State.ALIVE)
        {
            b = Brushes.Black;
        }
        else if (s == State.DEAD)
        {
            b = Brushes.White;
        }

        return b;
    }


    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top