我有一个通用视图,在其中我将一些特定视图"注入"到包含的ContentControl
中(我使用这些帮助创建了该功能->help1-help2)。
我观点的基本来源是:
MyGenericView.xaml
<UserControl x:Class="MyNS.MyGenericView"
... >
<UserControl.Resources>
<vml:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</UserControl.Resources>
<Grid DataContext="{Binding MyGenericViewModel, Source={StaticResource Locator}}">
<ContentControl Content="{Binding MyObject}" />
</Grid>
</UserControl>
CustomerView.xaml
<UserControl x:Class="AnotherNS.CustomerView"
... >
<Grid>
<StackPanel Orientation="Vertical">
<Label Content="Description" />
<TextBox Text="{Binding description}" />
</StackPanel>
</Grid>
</UserControl>
Crud.xaml
:一个资源字典,我用它来"解决"要显示的正确视图,这取决于泛型视图提供的MyObject
对象的DataType
。
<ResourceDictionary ... >
<DataTemplate DataType="{x:Type mo:Customer}">
<vw:CustomerView />
</DataTemplate>
<DataTemplate DataType="{x:Type mo:Product}">
<vw:ProductView />
</DataTemplate>
...
</ResourceDictionary>
它运行良好。我可以通过"特定"视图(客户、产品等)管理MyObject
。
嗯。这就是我的问题:
所有特定的视图都有自己的ViewModel,当然,它们管理各自视图的数据。但我不知道(在视图模型上)我正在处理的对象(MyObject)是什么,因为Generic View将其提供给了Specific View,而不是视图模型。
有没有办法让特定视图的ViewModels知道"指挥"视图的对象
在MVVM Light中,您将发送一条发布者/订阅者风格的广播消息,该消息将允许您与"托管"视图模型进行通信,而不必硬引用"托管"控件中的"托管"控制。
这允许"托管"控件与"托管"控制保持解耦,并在两者之间进行通信。
编辑:
在MVVM Light中,有一个信使对象可以为您处理许多细节。您可以创建将不同的消息和它们发送的参数分开的消息类。你也可以指定一个"令牌",只指定一个特定的字符串(我通常在一个类中设置一组常量来容纳我的各种"令牌"),它只允许该消息和该令牌的子订阅者接收消息。我在下面包含了一个代码示例,说明我在MVVM Light的v3中的MVVM Light中使用的内容。您需要确保从消息中注销,因为它不使用弱事件模式。
如果你不想使用MVVM Light,你可以在你的发布者/订阅者模型中使用同样的想法,你只需要确定发布者发送的代币是否是订阅者在你自己的上寻找的代币
public static class DescriptiveMessageName
{
public static void Send(object args)
{
Messenger.Default.Send(args, "SpecificToken");
}
public static void Send(object args, string token)
{
Messenger.Default.Send(args, token);
}
public static void Register(object recipient, Action<object> action)
{
Messenger.Default.Register(recipient,
"SpecificToken", action);
}
public static void Register(object recipient, string token, Action<object> action)
{
Messenger.Default.Register(recipient,
token, action);
}
public static void UnRegister(object recipient)
{
Messenger.Default.Unregister<object>(recipient);
}
public static void UnRegister(object recipient, Action<object> action)
{
Messenger.Default.Unregister<object>(recipient, action);
}
}