【问题标题】:WPF DataGrid binding confusionWPF DataGrid 绑定混乱
【发布时间】:2014-03-30 15:50:28
【问题描述】:

我对 WPF 数据绑定有点困惑。我尝试了很多示例,但我认为我不了解该主题的基础知识。

我有以下数据网格,绑定到 ObservableCollection(Of T),其中 T 类有一个 Name 属性,显示在 datagrid 列中。我的 T 类还实现了 INotifyPropertyChanged 并在 Name 属性更改时正确触发事件。

<DataGrid Grid.Row="1" Name="MyDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding}" >
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="NameColumn" Header="Name" Binding="{Binding Name}" />
    </DataGrid.Columns>
</DataGrid>

然后,在代码隐藏类中,我拥有了为数据网格提供数据的底层集合。

public ObservableCollection<T> MyCollection 
{
    get;
    set;
}

最后,当我的应用程序启动时,我加载“MyCollection”属性并告诉数据网格使用该集合。

public void InitApp() 
{
    MyCollection = [... taking data from somewhere ...];
    MyDataGrid.ItemsSource = MyCollection;
}

一切正常(数据显示正确)。但是,如果我重新加载集合(再次从某个地方获取完全不同的数据),如果我不再执行 MyDataGrid.ItemsSource = MyCollection;指令,数据网格没有更新。

我认为每次重新加载数据时都使用 XXX.ItemsSource = YYY 不是一个好习惯,所以我想我做错了什么。在一些示例中,我看到 XAML DataGrid 的绑定方式如下:

<DataGrid ItemsSource="{Binding CollectionName}">
  ...
</DataGrid>

我猜是为了使用该集合,因此无需以编程方式执行 .ItemsSource ......但我无法让它运行。

谁能告诉我隧道尽头的光?

【问题讨论】:

    标签: c# wpf xaml binding datagrid


    【解决方案1】:

    您没有解释最重要的部分是如何实现填充?如果您通过将新集合引用分配给旧变量来做到这一点,那么它将不起作用,因为集合是一种引用类型,以任何方式解决您的问题,您可以做两件事之一(除了您的解决方案): 第一个是将 ObservableCollection 定义为窗口中的 Dependency 属性,然后您可以使用它。 第二个也是最简单的方法是清除集合,然后使用源集合中的 foreach 循环添加新项目 这是第一种情况的示例:

    public static readonly DependencyProperty MyCollectionProperty = DependencyProperty.Register("MyCollection", typeof(ObservableCollection<T>), typeof(MainWindow));
    
    public ObservableCollection<T> MyCollection
    {
        get
        {
            return this.GetValue(MyCollectionProperty) as string;
        }
        set
        {
            this.SetValue(MyCollectionProperty, value);
        }
    }
    
    //assign the collection value at any time 
    MyCollection = ......
    
    //you can bind it as the past
    

    【讨论】:

      【解决方案2】:

      您可以对 DataGrid 的 ItemsSource 进行数据绑定,而不是手动分配它。只需将MyCollection 声明为公共属性,正确引发PropertyChanged 通知,并为您的DataGrid 设置DataContext(或为DataGrid 所在的Window 设置DataContext):

      private ObservableCollection<MyClass> _myCollection 
      public ObservableCollection<MyClass> MyCollection 
      {
          get { return _myCollection; }
          set 
          {
              _myCollection = value;
              NotifyPropertyChanged("MyCollection");
          }
      }
      
      public void InitApp() {
           MyCollection = [... taking data from somewhere ...];
           MyDataGrid.DataContext = this;
      }
      
      <DataGrid ItemsSource="{Binding MyCollection}">
        ...
      </DataGrid>
      

      更新:

      您的方法还在 XAML 中声明绑定:

      <DataGrid Grid.Row="1" Name="MyDataGrid" 
                             AutoGenerateColumns="False"                           
                             ItemsSource="{Binding}"  >
      

      这应该可以在不设置 ItemsSource 的情况下工作,但将它的 DataContext 设置为集合:

      public void InitApp() {
           MyCollection = [... taking data from somewhere ...];
           MyDataGrid.DataContext = MyCollection;
      }
      

      理论上(因为我没有专门尝试过这个问题的场景),使用ItemsSource绑定你的DataGrid将在集合重新加载时自动更新,当手动设置ItemsSource时不能带来相同的效果。

      【讨论】:

      • 您必须实现 INotifyPropertyChanged 才能引发 PropertyChanged 事件。如果您使用的是 ObservableCollection,那么您无需费心引发事件。只需放置 MyCollection = new ObservableCollection();在您的构造函数中,然后将在您的 InitApp 方法中加载的项目添加到 MyCollection。这一切都假设您在数据网格中使用以下绑定:ItemsSource="{Binding MyCollection}"
      猜你喜欢
      • 2014-09-24
      • 2015-07-02
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-12
      • 1970-01-01
      • 2011-12-17
      相关资源
      最近更新 更多