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