【发布时间】:2016-02-16 18:11:41
【问题描述】:
我从事 WPF MVVM 项目。我在 MainWindow 的视图模型和 usercontrol 的视图之间进行通信,放在 MainWindow 内。
所以我有:
用户控件
主窗口
MainWindowViewModel
我的UserControl很简单:
<Grid MouseDown="UIElement_OnMouseDown">
<Rectangle Fill="BlueViolet" />
</Grid>
带有代码隐藏(在单击矩形时触发一个事件,并传递坐标):
public partial class FooUserControl : UserControl
{
public FooUserControl()
{
InitializeComponent();
}
public event EventHandler<BarEventArgs> BarClick;
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
double x = e.GetPosition(this).X;
double y = e.GetPosition(this).Y;
string value_to_pass = "[" + x + "," + y + "]";
BarEventArgs bar = new BarEventArgs() { Bar = 2, Foo = value_to_pass };
BarClick?.Invoke(sender, bar);
}
}
我的 MainWindow 没有代码隐藏。只是xml。如您所见,我通过命令将点击事件传递给 MainWindowViewModel:
<Window.DataContext>
<viewModels:MainWindowViewModel />
</Window.DataContext>
<Grid>
<local:FooUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="BarClick">
<cmd:EventToCommand Command="{Binding ClickedCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:FooUserControl>
</Grid>
最后我的 MainWindowViewModel 有这个命令:
public class MainWindowViewModel : ObservableObject
{
public ICommand ClickedCommand => new RelayCommand<BarEventArgs>(o => Clicked(o.Foo));
private void Clicked(string a)
{
Debug.WriteLine("Clicked " + a);
}
}
因此,通过命令从 UserControl 的视图到 MainWindow 的视图模型的通信效果很好。但是,我该如何以相反的方式进行交流?从 MainWindowViewModel 到 UserControl 的视图?
【问题讨论】:
-
您想进行什么样的交流...?您可以寻找双向绑定。
-
在 UserControl 的表面上公开一个 ICommand。在您的 ViewModel 中绑定到它。现在 UserControl 可以直接与您的视图模型通信。沙赞。通讯回来了?在 UserControl 上公开它需要的任何属性。也许是一个点?或者也许是鞋子?我不知道。现在,视图模型将它们的属性设置为所需颜色的鞋子,并且通过更改通知,UserControl 可以自行更新。您拥有 MVVM 批准的双向通信。布拉姆。
-
您的
FooUserControl是否应该可以跨应用程序重用(=UserControl)或特定于您的应用程序(=View)。 UserControls 没有 ViewModel(只提供绑定到一个的依赖属性),只有 Views 有特定的 viewmodels (UserView=>UserViewModel)。 -
@Tseng 这就是我所拥有的。当我说“ViewModel”时,我指的是放置 FooUserControl 的视图的视图模型。
-
这就是
INotifiyPropertyChanged和INotifyCollectionChanged接口的用途,当值发生变化时告诉视图,你显然应该知道这一点,因为你实现了一个ObservableObject这听起来像一个类型实现INotifyPropertyChanged(INPC)