【问题标题】:Binding properties of multiple tree views to the same ViewModel将多个树视图的属性绑定到同一个 ViewModel
【发布时间】:2011-09-20 03:02:30
【问题描述】:

我正在研究一个 MVVM 实现,我将在其中生成多个视图(并排),每个视图都包含一个树控件。

每个视图都有一个相似的树,其中包含[几乎]所有相同项目的副本。

我想同步所有视图/TreeView 的 IsExpanded 属性..

意思是,如果我折叠一个节点,我希望所有节点都折叠(有些用于列宽等)。

执行此操作的一种方法是将所有视图绑定到同一个视图模型,并在该视图模型上具有 DependencyProperty,并在每个视图上将绑定设置为双向。但是,我需要将每个视图绑定到单独的视图模型,以便它可以显示唯一值。我只需要同步树的一些属性,例如 IsExpanded 和 Width。

这里最好的方法是什么?

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    您可以使用它的PrismEventAggregator 服务在视图模型之间交换数据。

    【讨论】:

    • 非常好,我不知道谢谢!但看起来该解决方案更适合事件聚合?还是我也可以将布尔视图属性绑定到它?
    • @Sonic Soul:创建自定义类 TreeViewState 派生自 CompositePresentationEvent. Class contains MyItem` 和 bool - 表示状态,也是树视图的标识符(第一个或第二个)。每个视图模型都会在状态发生变化时发布事件并订阅它们。
    【解决方案2】:

    没有理由不能在单个 ViewModel 中拥有不同的集合,如果这是最好的设计选项的话。特别是如果您的多个树/集合是从一些“完整集合”中过滤出来的;它实际上可能更有意义。

    只需将多个集合添加到您的 ViewModel,然后绑定到它们。

    public class MyViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<MyItem> FirstTreeCollection 
        { 
            get
            {
                // whatever you need to do here
            }
        }
    
        public ObservableCollection<MyItem> SecondTreeCollection 
        { 
            get { /* etc */ }
            set { /* etc */ }
        }
        // etc
    
        public bool Collapsed
        {
            get;
            set;
        }
    }
    

    你的视图应该相应地绑定

    // in your first view that contains a tree
    <UserControl x:Class="View1" ...>
        <TreeView Name="FirstTree" 
                  ItemsSource={Binding FirstTreeCollection}
                  Collapsed={Binding Collapsed} ... >
    
    // & in your second view that contains a tree
    <UserControl x:Class="View2" ...>
        <TreeView Name="SecondTree" 
                  ItemsSource={Binding SecondTreeCollection}
                  Collapsed={Binding Collapsed} ... >
    

    为了澄清,我建议您对所有这些包含树的视图使用单个 ViewModel

    【讨论】:

    • 同意。但你能详细说明我如何实现这个吗?
    • 不知道结果如何……我只有一棵树。它绑定到我的视图模型。我只需要将我提到的 2 个属性绑定到一些共享视图模型。所以实际上我的树视图将绑定到 2 个不同的模型......不知道该怎么做
    • 查看我的编辑。我建议您为包含树的视图使用单个 VM。
    【解决方案3】:

    ViewModel 不需要 DependencyPropery——它只需要公开一个实现 INotifyPropertyChanged 的​​属性。

    这两个 ViewModel 需要以某种方式共享状态,并公开表示该状态的属性。您如何共享状态很大程度上取决于您的 ViewModel 的实例化方式(可能还有其他因素)。例如,如果您的两个 VM 正在由某个父对象实例化,则父对象可能会创建一个实例并将其传递给它们的构造函数中的两个 VM。

    【讨论】:

    • 如果我理解正确,所有视图都会有一个状态实例,在我的树标记中我会像这样绑定它: IsExpanded={Binding MainState.IsExpanded} ?这就是你的想法吗?
    • 所有 ViewModel 都会有一个状态实例。然后折叠一个区域中的状态会将更改传播到共享状态,然后返回到视图。也就是说,如果像 Kirk 建议的那样使用单个 ViewModel 是一种选择,那将是更好的选择。
    【解决方案4】:

    如果您使用 xaml 显示树视图,则可以将每个树视图绑定到生成的第一个树视图。

    例如,您可以像这样使用一些绑定:

    <TreeView Name="FirstTreeView" />
    <TreeView Name="SecondTree" 
              IsExpended = {Binding Path=IsExpanded, ElementName=FirstTreeView, Mode=TwoWay}/>
    

    【讨论】:

    • 但是每个 TreeViewItem 的 IsExpanded 都会有所不同。第二个树视图如何知道哪些节点要同步到第一个中的哪些节点?
    • 所有树的层次结构是否相同?
    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-26
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多