【问题标题】:TreeViewItem Binding from code从代码中绑定 TreeViewItem
【发布时间】:2014-01-09 05:04:46
【问题描述】:

我知道它并不过分遵循 MVVM,但我没有太多选择。 我正在构建一个 WMI 浏览器(因此)

事物列出所有命名空间,然后用户单击他们想要的命名空间,然后在树视图框中列出所有类。

然后用户单击树视图框,方法/实例/属性将加载到单击的树视图项下方。

一切正常,我得到了带有属性/方法等的树视图项目。 它们甚至被扩展了,但是那里只有空白项目。 任何人都知道如何将 Ovbservablecollections 绑定到树视图项目列表?

这里是代码。

我的观点:

public void TreeView_BaseClasses_Event_SelectionChanged(Object sender, RoutedPropertyChangedEventArgs<object> e)
{
   if (this.IsLoaded)
   {
      if (((TreeView)sender).Name == "TreeView_BaseClasses")
      {
         TreeView TheTreeView = e.OriginalSource as TreeView;

         TreeViewItem SelectionChanged = ((TreeView)sender).ItemContainerGenerator.ContainerFromIndex(TheTreeView.Items.IndexOf(TheTreeView.SelectedItem)) as TreeViewItem;
         SelectionChanged.Items.Add(new TreeViewItem()
         {
             Header = "Properties",
             ItemsSource = "BaseClassesData",
             DisplayMemberPath = "ClassProperties"
         }
         );
         SelectionChanged.Items.Add(new TreeViewItem()
         {
             Header = "Methods",
             ItemsSource = "BaseClassesData",
             DisplayMemberPath = "ClassMethods"
         }
         );
         SelectionChanged.Items.Add(new TreeViewItem()
         {
             Header = "Instances",
             ItemsSource = "BaseClassesData",
             DisplayMemberPath = "ClassInstances"
         }
         );
         SelectionChanged.Items.Add(new TreeViewItem()
         {
             Header = "Sub Classes",
             ItemsSource = "BaseClassesData",
             DisplayMemberPath = "ClassSubClasses"
         }
         );
         ThisViewModel.SelectedItem = SelectionChanged;
         ThisViewModel.Children();
         SelectionChanged.ExpandSubtree();
         SelectionChanged.IsSelected = true;
         e.Handled = true;
   }
}

我的视图模型

public void Children()
{
   base.GetClassData(SelectedItem.Header.ToString());
}

我的模特

 public void GetClassData(string ClassName)
 {
     ManagementClass EnumClasses = new ManagementClass(ClassName);
     ClassData NewClass = new ClassData();
     try
     {
        foreach (ManagementObject objClass in EnumClasses.GetSubclasses())
        {
            NewClass.ClassSubClasses.Add(objClass.ClassPath.ClassName);
        }
        foreach (ManagementObject objInstance in EnumClasses.GetInstances())
        {
            NewClass.ClassInstances.Add(objInstance.ToString());
        }
        foreach (PropertyData Prop in EnumClasses.Properties)
        {
            NewClass.ClassProperties.Add(Prop.Name);
        }
        foreach (MethodData meth in EnumClasses.Methods)
        {
            NewClass.ClassMethods.Add(meth.Name);
        }
        NewClass.ClassEnumeration();
     }
     catch {

     }
     finally
     {
         BaseClassesData.Add(NewClass);
     }
}
public class ClassData
{
    public String ClassName { get; set; }
    public String ClassPath { get; set; }
    public ManagementScope ClassScope { get; set; }
    public ISite ClassSite { get; set; }
    public String ClassNamespace { get; set; }
    public ObservableCollection<String> ClassInstances { get; set; }
    public ObservableCollection<String> ClassProperties { get; set; }
    public ObservableCollection<String> ClassSubClasses { get; set; }
    public ObservableCollection<String> ClassMethods { get; set; }
    public ClassData()
    {
        ClassInstances = new ObservableCollection<string>();
        ClassProperties = new ObservableCollection<string>();
        ClassSubClasses = new ObservableCollection<string>();
        ClassMethods = new ObservableCollection<string>();
    }
    public void ClassEnumeration()
    {
        if (ClassName != null)
        {
           ClassPath = new ManagementClass(ClassName).ClassPath.Path;
           ClassScope = new ManagementClass(ClassName).Scope;
           ClassSite = new ManagementClass(ClassName).Site;
           ClassNamespace = new ManagementClass(ClassName).ClassPath.NamespacePath;
         }
     }
 }

【问题讨论】:

  • 我发现我可以使用 ItemsSource = ThisViewModel.ViewBaseClassesData[0].ClassProperties,但必须有更好的方法。这是我访问我的视图模型的视图,这是不好的
  • “一切正常,我得到了带有属性/方法等的树视图项目。它们甚至被扩展了,但是那里只有空白项目。” - TreeView 只是显示您拥有的数据。空白 TreeViewItems 表示您的集合中有空数据项。
  • 我检查了数据。及其有效。

标签: c# wpf mvvm treeview


【解决方案1】:

是的,你是对的,这没有遵循 MVVM,问题在于你如何设置 ItemSource -

ItemsSource = "BaseClassesData",

我认为您可能必须先指定 TreeNode 的 DataContext,然后创建绑定以指定 ItemSource(而不是仅指定 ItemsSource = "BaseClassesData") 或者直接指定您在评论中提到的 ItemSource。

以上两个css都需要你在View中访问你的ViewModel,View accessing ViewModel没有错;在 MVVM 视图中总是依赖于 ViewModel 并且总是知道并使用它(间接通过绑定和直接在代码中)。

最后,万一这不仅仅是临时工。项目并且需要在未来维护/增强我建议您实施适当的 MVVM;你会遇到很多需求,比如选择、扩展、动态加载、搜索等,而在代码中完成所有这些将非常繁琐且无法维护。

请看下面的文章来做到这一点-

Simplifying the WPF TreeView by Using the ViewModel Pattern

还可以查看以下 SO question,其中包含使用 MVVM 执行非常相似的代码 -

WPF: Binding TreeView in MVVM way step by step tutorial

【讨论】:

  • 正如我所说,我知道它不遵循 MVVM 模式。但是我的模型获取所有数据都没有问题。我这样做只是为了测试。我现在的问题是如何让我的数据显示。我找不到任何关于将类绑定到源是动态的多个树视图层的教程。看起来我可能不得不将我的整个树视图放在一个可观察的集合中,我不想这样做,因为类数据在其他地方使用。
猜你喜欢
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 2023-03-07
  • 2011-05-05
  • 2016-10-09
  • 2014-01-14
相关资源
最近更新 更多