15

I have

 <DataGridCheckBoxColumn 
     Binding="{Binding Path=Foo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
 />

And

 public bool Foo{ get; set; }

Checking/Unchecking sets Foo, but setting Foo in code does not change the Checkbox state. Any Suggesitons?

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Matt
  • 5,461
  • 7
  • 36
  • 43

2 Answers2

22

You need to raise the PropertyChanged event when you set Foo in your DataContext. Normally, it would look something like:

public class ViewModel : INotifyPropertyChanged
{
    private bool _foo;

    public bool Foo
    {
        get { return _foo; }
        set
        {
            _foo = value;
            OnPropertyChanged("Foo");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

If you call Foo = someNewvalue, the PropertyChanged event will be raised and your UI should be updated

slow
  • 566
  • 4
  • 17
Andrew
  • 1,482
  • 9
  • 16
0

I spent hours looking for a complete answer to this issue. I guess some people assume that other people searching this issue know the basics - sometimes we don't. A very important part about setting the form's data context was usually missing:

    public YourFormConstructor()
    {
        InitializeComponent();
        DataContext = this;                 // <-- critical!!
    }

My checkbox control was set up in the xaml file like this:

<CheckBox x:Name="chkSelectAll" IsChecked="{Binding chkSelectAllProp, Mode=TwoWay}" HorizontalAlignment="Left"/>

The "Path=" and "UpdateSourceTrigger=..." parts appear to be optional, so I left them out.

I am using this checkbox in a ListView header column. When someone checks or unchecks the checkbox, I want all the items in the ListView to also be checked or unchecked (select/unselect all functionality). I left that code in the example (as "optional logic") but your checkbox value logic (if any) would replace this.

The ListView contents are set by browsing for a file, and when a new file is selected, code sets the ListView ItemsSource and the CheckBox is checked (selecting all the new ListView items), which is why this two-way operation is required. That portion of the code is not present in this example.

The code in the xaml.cs file to handle the CheckBox looks like this:

    // backing value
    private bool chkSelectAllVal;

    // property interchange
    public bool chkSelectAllProp
    {
        get { return chkSelectAllVal; }
        set
        {
            // if not changed, return
            if (value == chkSelectAllVal)
            {
                return;
            }
            // optional logic
            if (value)
            {
                listViewLocations.SelectAll();
            }
            else
            {
                listViewLocations.UnselectAll();
            }
            // end optional logic
            // set backing value
            chkSelectAllVal = value;
            // notify control of change
            OnPropertyChanged("chkSelectAllProp");
        }
    }

    // object to handle raising event
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
pwrgreg007
  • 313
  • 3
  • 13