让 ViewModel 知道 View 的通用对象 [英] Let the ViewModel know the generic object of the View

查看:55
本文介绍了让 ViewModel 知道 View 的通用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a generic view where I "inject" some specific view into a contained ContentControl (I created that feature with these help -> help 1 - help 2).

我的观点的基本来源是这些:

The basic source of my views are these:

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:我用来解决"要显示的正确视图的资源字典,具体取决于 MyObjectDataType> 通用视图提供的对象.

Crud.xaml: a resource dictionary which I use to "solve" what's the correct view to show, depending on the DataType of MyObject object provided by the generic view.

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

一切正常.我可以通过特定"视图(客户、产品等)管理 MyObject.

It's working fine. I can manage MyObject through the "specific" view (customer, product, etc).

嗯.这是我的问题:

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

All the specific views have their own ViewModels and, of course, they manage the respective views' data. But I don't know (on the viewmodel) what's the object (MyObject) I'm working with, because the Generic View provides it to the Specific View, not to the viewmodel.

有没有办法让特定视图的视图模型知道命令"视图的对象?

推荐答案

在 MVVM Light 中,您将发送发布者/订阅者样式的广播消息,该消息将允许您与托管"视图模型进行通信,而无需硬引用到托管"控件中的托管"控件.

In MVVM Light you would send a publisher/subscriber style broadcast message that would allow you to communicate with the "hosting" view model without having to have a hard reference to the "hosting" control in the "hosted" control.

这允许托管"控件与托管"控件保持分离,但仍可在两者之间进行通信.

This allows the "hosted" control to stay decoupled from the "hosting" control and yet communicate with between the two.

在 MVVM Light 中有一个信使对象可以为您处理很多细节.您可以创建消息类来保存不同的消息和它们单独发送的参数.您还可以指定一个令牌"只是一个特定的字符串(我通常在一个类中设置一组常量来容纳我的各种令牌"),它只允许该消息的订阅者和该令牌接收消息.我在下面包含了我在 MVVM Light v3 的 MVVM Light 中使用的代码示例,您需要确保从消息中取消注册,因为它不使用弱事件模式.

In MVVM Light there's a messenger object that takes care of a lot of the details for you. You can create message classes that keep different messages and the arguments they send seperate. You can also specify a "Token" just a specific string (I usualy setup a set of constants in a class to house my various "Tokens") that allows only the subsribers to that message and that token to receive the message. I've included a code sample below of what I use in MVVM Light in v3 of MVVM Light you need to make sure to unregister from the message because it does not use the weak eventing pattern.

如果你不想使用 MVVM Light,你可以在你的发布者/订阅者模型中使用相同的想法,你只需要确定发布者发送的令牌是否是订阅者正在寻找的令牌为你自己

If you didn't want to use MVVM Light you can use the same idea in your publisher/subscriber model, you'd just have to do the work on determining if the token the publisher sent is the token the subscriber is looking for on your own

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);
}

}

这篇关于让 ViewModel 知道 View 的通用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆