我正在从事WPF MVVM项目。我正在努力解决MainWindow
的视图模型与放置在MainWindow
内的usercontrol
的视图之间的通信问题。
所以我有:
用户控件
主窗口
主窗口视图模型
我的用户控件非常简单:
<Grid MouseDown="UIElement_OnMouseDown">
<Rectangle Fill="BlueViolet" />
</Grid>
使用代码-behind(当矩形被点击时触发事件并传递坐标):
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);
}
}
我的主窗口没有后台代码,只有xaml。如您所见,我通过命令将单击事件传递给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的视图?
FooUserControl
是否应该在应用程序之间可重用(=UserControl),还是只针对你的应用程序特定(=View)?UserControls 没有 ViewModel(只提供依赖属性以绑定到一个),只有 Views 有特定的 viewmodels(UserView
=>UserViewModel
)。 - TsengINotifiyPropertyChanged
和INotifyCollectionChanged
接口的作用,它们告诉视图值已经改变,而你显然应该知道这一点,因为你实现了一个名为ObservableObject
的类型,它听起来像是实现了INotifyPropertyChanged
(INPC)的类型。 - Tseng