【问题标题】:Bind ObservableCollection to a DataGrid after assigning new value分配新值后将 ObservableCollection 绑定到 DataGrid
【发布时间】:2011-06-27 06:18:28
【问题描述】:

这似乎是一个简单的问题,但我无法让它工作。

我有一个具有以下属性的 UserControl:

public ObservableCollection<HL7Message> source {get; set;}

还有如下绑定:

<data:DataGrid x:Name="dgMessages" Grid.Row="2" AutoGenerateColumns="True" 
ItemsSource="{Binding source}" ></data:DataGrid>

从父用户控件中,我在单击按钮时设置值:

messagesGrid.source = src; //messagesGrid is the name of the UserCntrol above

我希望我的 DataGrid 会更新,但事实并非如此。你能指出我做错了什么吗?

【问题讨论】:

    标签: data-binding datagrid silverlight-3.0 observablecollection


    【解决方案1】:

    Auto-properties 遗憾的是不支持更改通知。因此,如果您设置source-Property,DataGrid 将不会知道集合已更改。

    一种可能性是为messagesGrid.source-Property 实现INotifiyPropertyChanged

    class YourUserControlClass: INotifyPropertyChanged
    
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {    
        if (null != PropertyChanged) {        
               PropertyChanged(this,e);    
        }
      }
    
      ObservableCollection<HL7Message> m_source;
    
      public ObservableCollection<HL7Message> Source { g
            get{return m_source;}
            set{
                if(value != m_source){
                     m_source=value;
                     OnPropertyChanged("Source");
                } 
            }
      } 
      ....
    

    请注意,我用大写写了Source 的第一个字母,因为在.net 中,属性通常是这样写的。您必须相应地更改您的绑定,因为绑定区分大小写。

    <data:DataGrid x:Name="dgMessages" Grid.Row="2" AutoGenerateColumns="True"  ItemsSource="{Binding Source}" ></data:DataGrid> 
    

    【讨论】:

    • 有道理,谢谢!正如我在下面指出的,我对 ObservableCollection 已经实现 INotifyPropertyChanged 的​​事实感到困惑,我无法弄清楚它的含义。
    • 另一个问题 - 如果我只是将 dgMessages.ItemsSource = _source; 放入我的属性的“设置”部分是否正确
    • @Masha:如果你不调用 OnPropertyChanged("Source") 那么它将不起作用。但是,如果您要求省略 if 语句,这将起作用。但是,如果没有真正的变化,我个人认为提出变更通知是不好的做法。
    • 我明白你的意思,但我说的是省略整个INotifyPropertyChanged 接口,而只是将dgMessages.ItemsSource = _source; 放入集合中(你是对的,我应该在其中使用 if 语句无论如何),因为我需要做的基本上就是用 ObservableCollection 传递给它的任何内容来更新我的 dataGrid。
    • 是的,如果您直接设置 DataGrid 的源,这是可能的。不知道这在您的应用程序中是否有意义,但这会起作用。但是,我建议您真正深入研究这个 INotifyPropertyChanged-thing,也可能深入研究 DependencyProperties。这确实是 WPF 的重要组成部分,如果你得到它,你会喜欢它。例如,MVVM 模式也需要它,它非常适合编写 WPF!
    【解决方案2】:

    问题在于,当您单击按钮时source 的引用发生变化时,没有什么可以告诉 UI 自行更新。您需要将source 设置为依赖属性,或者实现INotifyPropertyChanged,并在source 的设置器中调用PropertyChanged 事件。

    private ObservableCollection<HL7Message> source;
    public ObservableCollection<HL7Message> Source 
    { 
      get
      {
        return this.source;
      }
    
      set
      {
        this.source = value;
        this.NotifyPropertyChanged(() => this.Source);
      }
    }
    

    【讨论】:

    • 让我感到困惑的是 ObservableCollection 已经实现了 INotifyPropertyChanged (在 MSDN 上的某处了解它),或者这是否意味着有 NotifyPropertyChanged() 事件可供我使用?
    • 至于依赖属性,MSDN说:要成为绑定的来源,属性不需要是依赖属性;您可以使用任何 CLR 属性作为绑定源。但是,为了成为绑定的目标,该属性必须是依赖属性。所以我不认为我可以使用它..
    猜你喜欢
    • 2013-09-07
    • 2012-12-19
    • 2016-09-13
    • 2012-04-02
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2016-11-01
    相关资源
    最近更新 更多