WPF CheckBox TwoWay Binding not working

前端 未结 2 1279
春和景丽
春和景丽 2020-12-20 11:53

I have

 

And

相关标签:
2条回答
  • 2020-12-20 12:38

    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));
        }
    
    0 讨论(0)
  • 2020-12-20 12:48

    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

    0 讨论(0)
提交回复
热议问题