WPF CheckBox TwoWay Binding не работает

У меня

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

и

 public bool Foo{ get; set; }

Проверка/снятие отметки с набора Foo, но установка Foo в коде не изменяет состояние флажка. Любые подсказки?

Ответ 1

Вам нужно вызвать событие PropertyChanged когда вы устанавливаете Foo в вашем DataContext. Обычно это будет выглядеть примерно так:

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));
        }
    }
}

Если вы вызываете Foo = someNewvalue, событие PropertyChanged будет Foo = someNewvalue, и ваш пользовательский интерфейс должен быть обновлен.

Ответ 2

Я часами искал полный ответ на этот вопрос. Я предполагаю, что некоторые люди предполагают, что другие люди, ищущие эту проблему, знают основы - иногда мы не знаем. Очень важная часть о настройке контекста данных формы обычно отсутствовала:

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

Мой флажок был установлен в файле xaml следующим образом:

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

Части "Path =" и "UpdateSourceTrigger =..." кажутся необязательными, поэтому я их пропустил.

Я использую этот флажок в столбце заголовка ListView. Когда кто-либо устанавливает или снимает флажок, я хочу, чтобы все элементы в ListView также были отмечены или сняты (выберите/отмените выбор всех функций). Я оставил этот код в примере (как "необязательная логика"), но логика значений вашего флажка (если есть) заменит это.

Содержимое ListView устанавливается путем поиска файла, и когда выбирается новый файл, код устанавливает ListView ItemsSource, и CheckBox проверяется (выбираются все новые элементы ListView), поэтому эта двусторонняя операция является обязательной. Эта часть кода отсутствует в этом примере.

Код в файле xaml.cs для обработки CheckBox выглядит следующим образом:

    // 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));
    }