开发者

Problem with ObservableCollection and INotifyPropertyChanged in MVVM

开发者 https://www.devze.com 2023-01-21 08:36 出处:网络
I have a chart control in XAML, anddatapoints that are bind to the control. The problem is when my ModelView changes the Collection of points the Chart control doesn’t get any notifications. I have t

I have a chart control in XAML, and datapoints that are bind to the control. The problem is when my ModelView changes the Collection of points the Chart control doesn’t get any notifications. I have tried dp, with ObservableCollection and INotifyPropertyChanged without any luck. I know that there is a difference between changing a field/property and making collection operations such as (add/remove/replace etc.) for the changes to propagate to the Chart control. But I haven’t got it to work. The change event is only trigg开发者_如何学Goered when I instance/reinstance the collection.

Does any have link to a working MVVM that works with collections?

Worth too know.


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); }
        }

The binding is correct and tested. Code in Window.Resources.

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

The binding of control.


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

In the ViewModel I use the following code to rise changes. (When using INotifyPropertyChanged)

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

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

When I use ObservableCollection I only add new data point to the collection.

WorkModels.Add(workModel);

Question on MVVM pattern on WPF?


Needs more code. How do you bind? What type is ObservableCollection of? Are you sure you are notyfing in class that is value of ObservableColletion?

Edit: Also change title of your question. This is little ambiguous and not really problem of your question.


You've got this:

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

Why are you binding to a static resource? how is that resource defined? Is it in the XAML itself? Are you sure you're actually updating the same instance of the model that the control is bound to?


Have you tried something like this...

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

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

Then whenever you modify ANY point within the DataPoints collection, you raise a property change event for the entire DataPoints set

    /// <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);
        }
    }

EDIT:
Try changing the resource type from StaticResource to DynamicResource...
http://msdn.microsoft.com/en-us/library/ms750613.aspx#staticdynamic
The resource could be being loaded with the page/window and never updated. That would explain the lack of event communication


Thank you for answers. I found the solution to the problem here. http://msdn.microsoft.com/en-us/library/aa970563.aspx

For a dependency property in general, the implementation pattern that you follow is that you define a CLR property wrapper, where that property is backed by a DependencyProperty identifier rather than a field or other construct. You follow this same pattern when you implement a collection-type property. However, a collection-type property introduces some complexity to the pattern whenever the type that is contained within the collection is itself a DependencyObject or Freezable derived class.

0

精彩评论

暂无评论...
验证码 换一张
取 消