关于WPF上的MVVM模式的问题?

关于WPF上的MVVM模式的问题?,wpf,wpf-controls,binding,Wpf,Wpf Controls,Binding,我有一个用户控件,比如说UC1。此用户控件具有viewmodelUC1\U vm。 在usercontrol UC1中,我有一个画布,其中实现了绘制曲线逻辑。此绘制曲线逻辑基于视图模型(UC1_vm)中的数据点特性 视图模型中的“数据点”属性会随着不同的条件而变化。数据点的生成写在视图模型中 我想将视图模型中的数据点属性绑定到用户控件(视图)中的绘制曲线逻辑。我希望无论何时在视图模型中更改数据点属性,画布都会调用draw curve方法 我是否可以设置画布的set any属性,该属性在更改时自动

我有一个用户控件,比如说UC1。此用户控件具有viewmodelUC1\U vm。

在usercontrol UC1中,我有一个画布,其中实现了绘制曲线逻辑。此绘制曲线逻辑基于视图模型(UC1_vm)中的数据点特性

视图模型中的“数据点”属性会随着不同的条件而变化。数据点的生成写在视图模型中

我想将视图模型中的数据点属性绑定到用户控件(视图)中的绘制曲线逻辑。我希望无论何时在视图模型中更改数据点属性,画布都会调用draw curve方法

我是否可以设置画布的set any属性,该属性在更改时自动调用on paint逻辑

请向我建议实现此场景的方法

编辑:感谢@Ray Burns给出了一个非常有效的观点

如果列表实现了
INotifyCollectionChanged
接口(例如
observetecollection
,请参见),或者对象实现了
INotifyPropertyChanged
(请参见),并且您正在将点绑定到视图,那么它应该自行排序(当然,只要绑定正确!)

我提到这一点是因为您指出您正在使用一个列表,该列表取决于设置方式,可能只工作一次,但从不更新

您能否使用示例代码更新问题,例如类/WPF标记/视图模型代码等,以获得更多指导。在这个空间里有很多空间可以移动


PK:-)

听起来您有一个DependencyProperty,它是UserControl中的点集合。注册时,请使用
FrameworkPropertyMetadata
元数据,并在元数据构造函数中指定
FrameworkPropertyMetadata选项.AffectsRender
。请注意,这仅在替换整个集合时有效(如果为集合引发PropertyChanged,但集合实例未更改,则仍不会调用绘制)

如果您的集合实现了
INotifyCollectionChanged
,则可以连接一个集合已更改的事件处理程序,该事件处理程序将使可视对象无效:

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();
}
public静态dependencProperty点property=dependencProperty.Register(
“积分”,
类型(IEnumerable),
类型(UC1),
新的FrameworkPropertyMetadata(空,
FrameworkPropertyMetadataOptions.AffectsRender,
OnPointsChanged);
公共数点
{
get{return(IEnumerable)GetValue(PointsProperty);}
set{SetValue(PointsProperty,value);}
}
私有静态void OnPointsChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
UC1 ctrl=d作为UC1;
如果(e.NewValue!=null&&e.NewValue为INotifyCollectionChanged)
((INotifyCollectionChanged)e.NewValue).CollectionChanged+=ctrl.PointsChanged;
如果(e.OldValue!=null&&e.OldValue为INotifyCollectionChanged)
((INotifyCollectionChanged)e.OldValue).CollectionChanged-=ctrl.PointsChanged;
}
私有无效点更改(对象发送方,NotifyCollectionChangedEventArgs e)
{
无效的(通常的);
}

-1:这是一个非常糟糕的标题。请编辑标题以反映有关您的问题的更具体的内容。IMHO,这个问题的标题仍然需要认真研究。至少应该提到,您的视图绑定到视图模型中的数据点列表。感谢Paul的快速回复。是的,我确实实现了InotifyPropertyChanged接口。我的问题是,我应该绑定视图中的列表点(viewmodel中的属性)的哪个属性,以便它在视图中调用draw curve方法?您的意思是说
INotifyCollectionChanged
不是
INotifyPropertyChanged
。ObservableCollection也实现了
INotifyPropertyChanged
,但它仅在Count属性更改时激发,而不是在替换集合成员时激发。顺便说一句,两周前我犯了完全相同的错误,伊托尔森纠正了我,所以我知道即使使用了多年,也很容易混淆两者。