【问题标题】:Let the ViewModel know the generic object of the View让 ViewModel 知道 View 的泛型对象
【发布时间】:2012-02-16 02:16:38
【问题描述】:

我有一个通用视图,我将一些特定视图“注入”到包含的 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:我用来“解决”显示正确视图的资源字典,具体取决于通用视图提供的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)是什么,因为通用视图将它提供给特定视图,而不是视图模型。

有没有办法让特定 View 的 ViewModel 知道正在“控制”该视图的对象?

【问题讨论】:

    标签: wpf mvvm prism viewmodel


    【解决方案1】:

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

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

    编辑:

    在 MVVM Light 中有一个 messenger 对象可以为您处理很多细节。您可以创建消息类,将不同的消息和它们发送的参数分开。您还可以仅指定一个特定字符串的“令牌”(我通常在一个类中设置一组常量来容纳我的各种“令牌”),它只允许该消息的订阅者和该令牌接收消息。我在下面包含了我在 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);
    }
    

    }

    【讨论】:

    • 我已经考虑过使用“发布者/订阅者”方法。不同的实例不会对哪个是正确的对象感到困惑吗?您可以更新答案并在其中插入示例吗?非常感谢。
    • 好吧。我已经在我的项目中使用了 MVVMLight。我将尝试使用它提供的“信使对象”。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多