2016-02-10 310 views
2

我有一个WPF DataGrid绑定到名为“Personnel”的ObservableCollection。 DataGrid中有一个可编辑的DataGridCheckBoxColumn。 CheckBoxColumn绑定到我的集合中名为“AircraftCommanderSelected”的布尔值。选中某一行并选中该复选框后,会触发一个事件来更新集合,以便每个“人员”的所有AircraftCommanderSelected值都设置为false(除刚刚设置为true的那个值外)。这就是说,我的集合正确更新,但我的数据网格不会'取消'以前选中的框,谁的绑定值已被更改为false。我如何通知价值已更改?以下是我的代码(为便于阅读而修改)。当ObservableCollection值更新时WPF Datagrid绑定不更新

public class Personnel 
{ 
     /// 
     ///Other objects removed for reading purposes. All follow same format. 
     /// 
     private bool aircraftCommanderSelected; 
     public bool AircrafCommanderSelected 
     { 
      get { return this.aircraftCommanderSelected; } 
      set 
      { 
       if(this.aircraftCommanderSelected != value) 
       { 
        this.aircraftCommanderSelected = value; 
        this.NotifyPropertyChanged("AircraftCommanderSelected"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     public void NotifyPropertyChanged(strin propName) 
     { 
      if(this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
      } 
     } 
} 

XAML

<DataGrid Name="dataGrid" AutoGenerateColumns="False" SelectedItem="{Binding Personnel}" CanUserDeleteRows="False" CanUserAddRows="False" IsReadOnly="False" SelectionMode="Single" CellEditEnding="dataGrid_CellEditEnding"> 
    <DataGrid.Columns> 
     <DataGridCheckBoxColumn local:DataGridUtil.Name="ac" Header="AC" Binding="{Binding AircraftCommanderSelected}"/> 
    </DataGrid.Columns> 
</DataGrid> 

代码

private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
{ 
     foreach (Personnel p in vm.personnel)//Loop through each item in the collection 
     { 
      //per.ID is the ID of the person who was just edited. 
      //This sets everyones value to false except the person that was just edited. 
      if (p.ID != per.ID) { p.AircraftCommanderSelected = false; } 
     } 
    } 

背后,当收集被修改,属性更改事件被激发,不应该将DataGrid更新?

我发现了一个解决方案,但它涉及多线程,这似乎是一个不正确的解决方案,这个问题。我也不喜欢它如何刷新整个网格,并取消选择我目前的选择

dataGrid.Dispatcher.BeginInvoke(new Action(() => dataGrid.Items.Refresh()), System.Windows.Threading.DispatcherPriority.Background); 

任何帮助表示赞赏。

感谢

-Justin

回答

2

有你需要检查的一系列事情:

  • 在你ObservableCollection实施INotifyPropertyChanged正确的对象? (不在其发布的代码中)
  • 是否有任何拼写错误或大小写属性更改?如果您使用.NET 4.6,则可以使用新的nameof()属性来确保这一点。
  • 如果这个值可以从后台代码被改变,则必须使用Mode=TwoWay

默认情况下,大多数绑定OneWay。如果您的绑定模式是单向的,并且您更改了代码后面的值,则绑定将会中断并且不再起作用,直到您重新加载XAML。

+0

谢谢!所有3个答案都将我引向解决方案,因为它是一个组合,但您的问题涵盖了大部分问题。我在我的NotifyPropertyChanged事件的字符串末尾有一个空格。修复以及将我的绑定模式更改为TwoWay并将NotifyPropertyChanged添加到我的类声明中解决了问题。 – Tronald

1

更新与BindingMode.TwoWay

<DataGridCheckBoxColumn local:DataGridUtil.Name="ac" Header="AC" Binding="{Binding AircraftCommanderSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

结合,因为你正试图从代码中更改值。

2

即使您的人事类别有PropertyChanged事件,其声明并不表示它实现INotifyPropertyChanged。更改类声明,使其显示如下:

public class Personnel : INotifyPropertyChange { 
    // rest of code here 
} 

此外,绑定需要两种方式。我不知道DataGridCheckBoxColumn的默认设置是什么,但是将其明确说明并不会让人伤心。

相关问题