【问题标题】:WPF Datagrid Bindings Not Updating When ObservableCollection Values Updated更新 ObservableCollection 值时 WPF Datagrid 绑定未更新
【发布时间】:2016-02-10 14:09:15
【问题描述】:

我有一个 WPF DataGrid 绑定到名为“Personnel”的 ObservableCollection。我在 DataGrid 中有一个可编辑的 DataGridCheckBoxColumn。 CheckBoxColumn 绑定到我的集合中名为“AircraftCommanderSelected”的布尔值。选择行并选中复选框时,将触发事件以更新集合,以便每个“人员”的所有飞行器组成的值都设置为false(除了设置为true的那个之外)。话虽如此,我的集合正在正确更新,但我的数据网格不会“取消选中”先前选中的框,其绑定值已更改为 false。如何通知值已更改?以下是我的代码(为便于阅读而修改)。

 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.Dispatcher.BeginInvoke(new Action(() => dataGrid.Items.Refresh()), System.Windows.Threading.DispatcherPriority.Background);

感谢任何帮助。

谢谢

-贾斯汀

【问题讨论】:

    标签: c# wpf xaml datagrid


    【解决方案1】:

    您需要检查一系列事项:

    • ObservableCollection 中的对象是否正确实现了INotifyPropertyChanged? (不在它发布的代码中)
    • 属性名称是否有任何拼写错误或大小写更改?如果您使用的是 .NET 4.6,则可以使用新的 nameof() 属性来确保这一点。
    • 如果值可以从代码隐藏中更改,那么您必须使用Mode=TwoWay

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

    【讨论】:

    • 谢谢!您的所有 3 个答案都使我找到了解决方案,因为它是多种事物的组合,但您的答案涵盖了大部分问题。在 NotifyPropertyChanged 事件中,我的字符串末尾有一个空格。修复该问题并将我的绑定模式更改为 TwoWay 并将 NotifyPropertyChanged 添加到我的类声明中解决了该问题。
    【解决方案2】:

    即使你的 Personnel 类有一个PropertyChanged 事件,它的声明并不表示它实现了INotifyPropertyChanged。更改类声明,使其变为:

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

    此外,绑定需要是两种方式。我不知道 DataGridCheckBoxColumn 的默认值是什么,但明确表示它不会有什么坏处。

    【讨论】:

      【解决方案3】:

      使用BindingMode.TwoWay更新您的绑定

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

      因为您正试图从代码中更改值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-31
        • 2021-08-31
        • 2013-01-02
        • 2013-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多