【问题标题】:How do you wire up views in Silverlight and MVVM using a TreeView?如何使用 TreeView 连接 Silverlight 和 MVVM 中的视图?
【发布时间】:2023-04-03 05:41:01
【问题描述】:

我正在构建一个 Silverlight 应用程序,该应用程序包含左侧列中的菜单选项 TreeView 和右侧列中的 ContentView。想法是TreeView的SelectedItemChanged事件会改变内容区域的视图。

实现这一目标的“最纯粹的 MVVM”方法是什么?

我的想法是有一个TreeMenuViewTreeMenuViewModel 来管理菜单事件,但在那之后我有点迷路了。我可以使用 EventAggregator 将消息从 TreeMenuViewModel 发送到“ContentViewModel”,然后根据消息 args 设置其当前的 ContentView——但这肯定会破坏 MVVM,因为 ViewModel 不应该知道 UI像视图这样的构造?

我在这里遗漏了一些简单的东西吗?

ViewModel 层如何驱动视图选择?

【问题讨论】:

    标签: c# .net silverlight mvvm


    【解决方案1】:

    我会创建一个ShellViewModel,它有:

    • ObservableCollection<ViewModelBase> AvailablePages
    • int SelectedPageIndex
    • ViewModelBase CurrentPage,返回AvailablePages[SelectedPageIndex]

    您的ShellView 可以是您想要的任何东西。如果您想在TreeView 中显示您的AvailablePages,请继续。只要记住将SelectedIndex绑定到`SelectedPageIndex

    在您的情况下,我将创建一个DockPanel,左侧的TreeView 绑定到AvailablePages,右侧的ContentControl 绑定ContentControl.Content 绑定到CurrentPage

    编辑

    这是一个例子

    <DockPanel>
        <TreeView DockPanel.Dock="Right"
                  ItemsSource="{Binding AvailablePages}"
                  SelectedItem="{Binding SelectedPageIndex}">
        ...
        </TreeView>
    
        <ContentControl Content="{Binding CurrentPage}" />
    </DockPanel>
    

    然后使用DataTemplates 定义包含CurrentPage 的ContentControl 的外观

    <Window.Resources>
        <DataTemplate DataType="{x:Type local:HomePageViewModel}" />
             <local:HomePageView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:CustomerViewModel}" />
             <local:CustomerView />
        </DataTemplate>
    </Window.Resources>
    

    【讨论】:

    • 瑞秋,谢谢,这是有道理的。我可以澄清一下,视图选择/绑定实际发生在哪里?在您的描述中,如果我理解正确,ContentControl.Content 绑定到 ViewModelBase 实例 (CurrentPage) - 这不应该绑定到视图吗?我敢肯定有一些简单的东西我没有在这里:)
    • @Malcom 我在答案中添加了一些示例代码。 ViewModel 包含实际的应用程序状态和导航,而 View 只是一个漂亮的 UI,允许用户与 ViewModel 交互。我通常使用 DataTemplates 将我的视图与他们的 ViewModel 相关联
    • 我正在使用 Silverlight,而 DataTemplates 似乎不支持 DataType 属性 - 还有其他想法吗?
    • @Malcum 我忘了 Silverlight... 我通常使用 DataTrigger 和自定义 ConverterDataTemplateSelector 来确定要显示的 DataTemplate
    • 我最终使用了 Prism 的 DataTemplateSelector 和您上面的技术,但我必须使用支持 DataType 属性的 Silverlight 5。
    【解决方案2】:

    好吧,我试一试

    在 TreeMenuViewModel 中:

    public string PropSelectedItem
    {
    get;
    set;
    }
    

    TreeMenuView:

    &lt;TreeView Context="{Binding TreeMenuViewModel}" Content="{Binding PropSelectedItem, Mode=OneWayToSource}"/&gt;

    在 ContentViewModel 中:

    public ViewModelBase PropSelectedItem
    {
    get
     {
    switch(TreeMenuViewModelStatic.PropSelectedItem)
    {
      case "Booo": return typeof(View1);
      case "Foo": return typeof(View2);
    }
    
    
      }
    private set;
    }
    

    在内容视图中:

    &lt;ContentControl Context="{Binding TreeMenuViewModel}" Content="{Binding PropSelectedItem, Mode=OneWay}"/&gt;

    这里需要一个值转换器

    【讨论】:

    • 要将字符串转换为视图?我想我明白了,如果我理解,您的 TreeView 会在 TreeViewModel 中设置所选项目(例如,一些字符串值“MenuItem1”),然后您的 ContentViewModel 将该项目公开给加载转换字符串值后适当的视图控件 - 对吗?
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    相关资源
    最近更新 更多