【问题标题】:How to Interact with 2 or More ViewModels如何与 2 个或更多 ViewModel 交互
【发布时间】:2013-12-03 23:44:10
【问题描述】:

我编写了一个工具,其中 ListBox 绑定到 ObserservableCollection<object>,并具有我定义的不同数据类型。我使用PropertyDataTemplateSelector 来呈现ListBox 中的数据。 PropertyDataTemplateSelector 引用了几个设置为UserControlsDataTemplates。有一个后台类通过检查object 类型然后应用正确的DataTemplatePropertyDataTemplateSelector 提供逻辑。

这是UserControlsMainWindow 的XAML 的缩写示例。

用户控件1

    <TextBlock Text="{Binding Path=Val1}"
               Style="{StaticResourse Yes}" />

    <Button Content="I'm Button 1"
            Command="{Binding Path=PathtoCommand1}"
            CommandParameter="{Binding Parameter1}"
            IsEnabled="{Binding IsEnabled1}" />

    <Button Content="I'm Button 2"
            Command="{Binding Path=PathtoCommand2}"
            CommandParameter="{Binding Parameter2}"
            IsEnabled="{Binding IsEnabled2}"
            Tag="{Binding Path="DataContext.TagItem2}">

       <Button.ContextMenu>
         <ContextMenu>
           <MenuItem IsCheckable="True"
                     IsChecked="{Binding Path=Tag}"
                     DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
         </ContextMenu>
       </Button.ContextMenu>

    </Button>
  </StackPanel>
</UserControl>

用户控制N

<UserControl x:Class="AwesomerControl">
  <StackPanel Orientation="Vertical">

    <TextBlock Text="{Binding Path=FancyName2}"
               Style="{StaticResourse Yes}" />

    <Button Content="Clicker 1"
            Command="{Binding Path=DoSomethingGreat1}"
            CommandParameter="{Binding Greatness1}"
            IsEnabled="{Binding IsTurnedOn1}" />

    <Button Content="Clicker 2"
            Command="{Binding Path=DoSomethingGreat2}"
            CommandParameter="{Binding Greaterness2}"
            IsEnabled="{Binding IsTurnedOn2}"
            Tag="{Binding Path="DataContext.TagItem2}">

       <Button.ContextMenu>
         <ContextMenu>
           <MenuItem IsCheckable="True"
                     IsChecked="{Binding Path=Tag}"
                     DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
         </ContextMenu>
       </Button.ContextMenu>

    </Button>
  </StackPanel>
</UserControl>

在这里,我将UserControls 设置为指定的DataTemplate。 UserControls 被移出以使 XAML 更易于阅读/导航。实际上,每个 UserControl 有几百行。

<Window.Resources>
  <DataTemplate x:Key"Template1">
     <customControls:AwesomeControl/>
  </DataTemplate>
  ...
  <DataTemplate x:Key"TemplateN">
     <customControls:AwesomerControl/>
  </DataTemplate>


  <dts:PropertyDataTemplateSelector x:Key="templateselector"
                                    Template1="{StaticResource Template1"}
                                    ...
                                    TemplateN="{StaticResource TemplateN"}
</Window.Resources>

ListBox 是这样定义的。

<ListBox ItemSource="{Binding Path=CollectionofMyObjects}"
         ItemTemplateSelector="{StaticResource templateselector}" />

我使用单个ViewModel 来驱动MainWindowUserControls

这就是我所在的地方,基本上。我目前正在按照我的意愿工作,但是在不断努力学习(这是我的第一个 MVVM/WPF/C# 项目)中,我想继续探索如何使我的代码“更好”(无论如何定义) .我不想在这里解决错误。所以为了避免一个一般/广泛的问题,我会问我想知道什么。有人可以纠正我,我会适当地更新“问题”

问题:我怎样才能为每个UserControls 生成一个ViewModel?某些ViewModels,对于UserControls,偶尔需要与MainWindow_ViewModel 进行双向通信。我的问题的主要症结在于弄清楚多个虚拟机将如何通信。

【问题讨论】:

    标签: c# wpf mvvm listbox viewmodel


    【解决方案1】:

    你已经接近了,但它还不是相当 MVVM。 ;)

    1. 首先,将与每个UserControl 相关的所有功能分解到它们自己的类中。这些是您的视图模型类。
    2. 您的控件现在应该成为“视图”类,它们应该拥有自己的标记文件。您可以使用DataTemplate.DataType 将视图模型类类型自动连接到其视图,而不是使用模板选择器。

    视图模型之间的通信有很多选项。为了进一步学习,我会考虑查看具有内置通信解决方案的轻量级 MVVM 框架。我个人最喜欢的是Caliburn.Micro,其中包括EventAggregator,该服务提供了以松散耦合的方式将对象从一个视图模型发布到另一个视图模型的能力。

    继续学习,你在正确的轨道上!

    【讨论】:

    • 真的没有MVVM吗?从我正在阅读的内容来看,他的做法是正确的。你能详细说明一下吗?但你是对的,模块化绝对可以改进。
    • 我做了一个快速编辑,以确保我们说的是同一件事。我的每个 UserControls 都被定义为一个单独的视图。这就是你讨论的模块化吗?我是否正确假设当您说“视图”类应该拥有自己的标记文件时,您的意思是这些文件的单独视图模型(而不是背后的代码)?
    • MVVM 应该利用多个视图以及视图模型。如果您只有 1 个视图模型和 1 个视图 (XAML) 文件,那么不用说您没有充分利用该模式。 :) 还有彼得,我的意思是每个用户控件都应该在它们自己的 .xaml 文件中定义(最好在“视图”文件夹中)。
    • 查理,感谢您的指点。我认为你给了我足够的帮助,让我朝着正确的方向前进。
    猜你喜欢
    • 2010-10-17
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2021-09-27
    • 2011-09-16
    • 1970-01-01
    相关资源
    最近更新 更多