MVVM中的ObservableCollection和INotifyPropertyChanged问题

时间:2010-10-27 05:41:47

标签: c# mvvm

我在XAML中有一个图表控件,以及绑定到控件的数据点。 问题是当我的ModelView更改点集合时,Chart控件不会收到任何通知。我试过dp,ObservableCollection和INotifyPropertyChanged没有任何运气。我知道更改字段/属性和进行集合操作(​​如添加/删除/替换等)以使更改传播到Chart控件之间存在差异。但我还没有把它付诸实践。只有在我实例化/重新安装集合时才会触发更改事件。

是否有链接到适用于集合的工作MVVM?

值得知道。


public class ObservableCollection : Collection, INotifyCollectionChanged, INotifyPropertyChanged


        public static DependencyProperty WorkModelsProperty = DependencyProperty.Register("WorkModels", typeof(ObservableCollection), typeof(Chart),
            new PropertyMetadata(new ObservableCollection { }, new PropertyChangedCallback(
            (sender, args) =>
            {
                Debugger.Break(); //trigged only when collection got new instance
            })));

        public ObservableCollection WorkModels
        {
            get { return (ObservableCollection)GetValue(WorkModelsProperty); }
            set { SetValue(WorkModelsProperty, value); }
        }

绑定是正确的并经过测试。 Window.Resources中的代码。

ObjectDataProvider ObjectType="{x:Type vm:ListWorkViewModel}" x:Key="ListWorkViewModel"

控制的绑定。


WorkModels="{Binding Source={StaticResource ListWorkViewModel}, Path=WorkModels}"

在ViewModel中,我使用以下代码进行更改。 (使用INotifyPropertyChanged时)

WorkModels.Add(workModel);
this.RaisePropertyChanged("WorkModels");

protected void RaisePropertyChanged(string propertyName)
{
     VerifyPropertyName(propertyName);
     if (PropertyChanged != null)
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

当我使用ObservableCollection时,我只将新数据点添加到集合中。

WorkModels.Add(workModel);

Question on MVVM pattern on WPF?

4 个答案:

答案 0 :(得分:0)

需要更多代码。你怎么绑? ObservableCollection是什么类型的?你确定你在课堂上不是ObservableColletion的价值吗?

编辑:同时更改问题的标题。这有点模棱两可,并不是你问题的真正问题。

答案 1 :(得分:0)

你有没有试过这样的东西......

private IEnumerable<DataPoint> _DataPoints;
public IEnumerable<DataPoint> DataPoints
{
    get
    {
        return _DataPoints;
    }

    set
    {
        if (_DataPoints != value)
        {
            _DataPoints = value;
            this.OnPropertyChanged("DataPoints");
        }
    }
}

然后,只要修改DataPoints集合中的任何点,就会为整个DataPoints集引发属性更改事件

    /// <summary>
    /// Raised when a property on this object has a new value.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises this object's PropertyChanged event.
    /// </summary>
    /// <param name="propertyName">The property that has a new value.</param>
    protected virtual void OnPropertyChanged(string propertyName)
    {
        //this.VerifyPropertyName(propertyName);

        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

编辑:
尝试将资源类型从StaticResource更改为DynamicResource ...
http://msdn.microsoft.com/en-us/library/ms750613.aspx#staticdynamic
资源可能正在加载页面/窗口,并且永远不会更新。这可以解释缺乏事件沟通

答案 2 :(得分:0)

你有这个:

WorkModels="{Binding Source={StaticResource ListWorkViewModel}, Path=WorkModels}"

为什么要绑定到静态资源?该资源是如何定义的?它在XAML本身吗?您确定您实际上正在更新控件绑定的模型的同一实例吗?

答案 3 :(得分:0)

谢谢你的回答。我在这里找到了问题的解决方案。 http://msdn.microsoft.com/en-us/library/aa970563.aspx

对于一般的依赖项属性,您遵循的实现模式是您定义CLR属性包装器,其中该属性由DependencyProperty标识符而不是字段或其他构造支持。实现集合类型属性时,您遵循相同的模式。但是,只要集合中包含的类型本身是DependencyObject或Freezable派生类,集合类型属性就会为模式带来一些复杂性。