views:

81

answers:

2

I have a user control let say UC1 . This user control have viewmodel UC1_vm.

In the usercontrol UC1 I have a canvas in which drawing curve logic is implemented. This drawing curve logic is based on the data points property in the view model ( UC1_vm).

The data points property inside the view model change with different condition. The generation of data points is written in the View Model.

I want to bind the data points property in the view model to the draw curve logic inside the User control (view). I want whenever the data point property is changed in the view model , the canvas calls the draw curve method.

Can I set the set any property of canvas which when changed it calls the on paint logic auto matically?

Please suggest me the approach of implementing this scenario!!

A: 

EDIT: Thanks @Ray Burns for a rather valid point!

If your list implements the INotifyCollectionChanged interface (e.g. ObservableCollection<Point>, see ObservableCollection@msdn) or the objects implement INotifyPropertyChanged (see INotifyPropertyChanged @msdn) and you are binding the points to the view then it should sort itself out (as long as the binding is correct of course!)

I mention that because you indicated you were using a List which depending on how things are set up may work once but never update.

Can you update the question with sample code, e.g. the class/WPF markup/view model code etc to get more guidance. There is a lot of room to move in this space...

PK :-)

Paul Kohler
Thanks Paul for the quick reply. Yes I do have implemented the INotifyPropetyChanged interface. My question is which propety of canvas do I bind the List<double> Points ( property in the viewmodel) in view so that it calls the draw curve method inside the view?
Ashish Ashu
Got the WPF markup, that would make it more clear...
Paul Kohler
@Paul: You meant to say `INotifyCollectionChanged` not `INotifyPropertyChanged`. ObservableCollection *does* implement `INotifyPropertyChanged` as well, but it only fires when the Count property changes, not when collection members are replaced. By the way, I made exactly the same mistake two weeks ago and itowlson corrected me, so I know it is easy to confuse the two even after using them for years and years.
Ray Burns
A: 

It sounds like you have a DependencyProperty that is the collection of points in your UserControl. When you register it, use the FrameworkPropertyMetadata metadata, and specify the FrameworkPropertyMetadataOptions.AffectsRender in the metadata constructor. Note that this will only work if the entire collection is replaced (if you raise PropertyChanged for the collection, but the collection instance hasn't changed, your paint still won't get called).

If your collection implements INotifyCollectionChanged, then you can wire up a collection changed event handler that invalidates the visual:

public static DependencyProperty PointsProperty = DependencyProperty.Register(
    "Points",
    typeof(IEnumerable<Point>),
    typeof(UC1),
    new FrameworkPropertyMetadata(null, 
        FrameworkPropertyMetadataOptions.AffectsRender,
        OnPointsChanged));

public IEnumerable<Point> Points
{
    get { return (IEnumerable<Point>)GetValue(PointsProperty); }
    set { SetValue(PointsProperty, value); }
}

private static void OnPointsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    UC1 ctrl = d as UC1;
    if (e.NewValue != null && e.NewValue is INotifyCollectionChanged)
        ((INotifyCollectionChanged)e.NewValue).CollectionChanged += ctrl.PointsChanged;

    if (e.OldValue != null && e.OldValue is INotifyCollectionChanged)
        ((INotifyCollectionChanged)e.OldValue).CollectionChanged -= ctrl.PointsChanged;
}

private void PointsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    InvalidateVisual();
}
Abe Heidebrecht