让ViewModel知道View的通用对象

时间:2012-02-16 02:16:38

标签: wpf mvvm prism viewmodel

我有一个通用视图,我将一些特定视图“注入”到包含的ContentControl中(我使用这些帮助创建了该功能 - > help 1 - help 2)。

我的观点的基本来源是:

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:一个资源字典,用于“解决”要显示的正确视图,具体取决于通用视图提供的DataType MyObject对象。

<ResourceDictionary ... >
    <DataTemplate DataType="{x:Type mo:Customer}">
        <vw:CustomerView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type mo:Product}">
        <vw:ProductView />
    </DataTemplate>
    ...
</ResourceDictionary>

工作正常。我可以通过“特定”视图(客户,产品等)管理MyObject

好。那是我的问题:

所有特定视图都有自己的ViewModel,当然,它们管理各自的视图数据。但我不知道(在viewmodel上)我正在使用的对象(MyObject)是什么,因为Generic View将它提供给特定视图,而不是视图模型。

有没有办法让特定视图的ViewModel知道“命令”视图的对象?

1 个答案:

答案 0 :(得分:1)

在MVVM Light中,您将发送一个发布者/订阅者样式的广播消息,该消息允许您与“托管”视图模型进行通信,而无需在“托管”控件中对“托管”控件进行硬引用。 / p>

这允许“托管”控件与“托管”控件保持分离,并在两者之间进行通信。

编辑:

在MVVM Light中,有一个信使对象可以为您处理很多细节。您可以创建保留不同消息的消息类以及它们分开发送的参数。您还可以指定一个“Token”只是一个特定的字符串(我通常在类中设置一组常量来容纳我的各种“Tokens”),它只允许该消息的子记录和该令牌接收消息。我已经在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);
}

}