每个子项集合的WPF TreeView“文件夹节点”

时间:2011-02-24 21:16:14

标签: wpf

我有一个类有几个集合,我想在树视图中显示每个集合的'文件夹节点'。非常像SQL Management Studio显示一个数据库,其中包含“Tables”的文件夹,其中包含所有表格,“视图”等节点。

假设我的班级看起来像这样

class DataBase{
   public IEnumerable<Table> Tables {get;}
   public IEnumerable<View> Views {get;}
   public IEnumerable<StoredProc> Procedures {get;}
} 

XAML如何在我的树视图中大致看到这个?

+ myDatabase
  + Tables
    + table1
      + Columns
        - Column1
        - Column2
      + Indexes 
    - table2
  + Views
    - View1
    - View2
  + Stored Procedures
    - SP1
    - SP2

我环顾四周但是我找不到干净的方法来做到这一点,这在winforms中过去是微不足道的,因为你可以添加该文件夹节点并保持它。无法轻易在WPF中飞行。

编辑: 取得了一些进展(我只是认为我可以通过xaml添加节点并保持这些节点)

<TreeView Name="tvModel" Width="200" DockPanel.Dock="Left">           
        <TreeViewItem Name="tnDatabase">
            <TreeViewItem Name="tnTables" Header="Tables"/>
            <TreeViewItem Name="tnViews" Header="Views" />
            <TreeViewItem Name="tnProcs" Header="Stored Procedures" />
        </TreeViewItem>
    </TreeView>

然后在代码中:

 tnTables.ItemsSource = dataBase.Tables;

等。

但现在我陷入了下一站:每个Table类看起来都像这样:

class Table {
   IEnumerable<Column> Columns {get;}
   IEnumerable<Index> Indexes {get;}
}

所以现在我想要节点'列'和'索引'将这些项分组,对于每个表节点就像数据库级一样。现在它不再那么容易了,因为不再需要一次这样做,需要为每个表完成。我更新了上面的树例子来说明。

Edit2:忘记上面的内容,doen; t嵌套到最后,viewmodel效果更好。如果有人需要这样做,这最终对我有用:

// folder class
class CollectionFolder {
    public string Name { get; set; }
    public IEnumerable Collection { get; set; }
}

class DataBase {
    public IEnumerable<Table> Tables { get { for (int i = 0; i < 10; i++) yield return new Table() { Name = "Table " + i }; } }
    public IEnumerable<View> Views { get { for (int i = 0; i < 10; i++)  yield return new View() { Name = "View" + i }; } }
    public IEnumerable<SProc> Sprocs { get { for (int i = 0; i < 10; i++)  yield return new SProc() { Name = "Stored Procedure" + i }; } }

    // wrap each collection in folder
    public IEnumerable<CollectionFolder> Collection {
        get {
            yield return new CollectionFolder() { Name = "Tables", Collection = Tables };
            yield return new CollectionFolder() { Name = "Views", Collection = Views };
            yield return new CollectionFolder() { Name = "Stored Procedures", Collection = Sprocs };
        }
    }
}    

class Table {
    public string Name { get; set; }
    public IEnumerable<CollectionFolder> Collection {
        get {
            yield return new CollectionFolder() { Name = "Columns", Collection = Columns };
            yield return new CollectionFolder() { Name = "Indexes", Collection = Indexes };
        }
    }
    public IEnumerable<Column> Columns { get { for (int i = 0; i < 10; i++)  yield return new Column() { Name = "Column " + i }; } }
    public IEnumerable<Index> Indexes { get { for (int i = 0; i < 10; i++)  yield return new Index() { Name = "Index " + i }; } }
}

class Column { public string Name { get; set; } }
class Index { public string Name { get; set; } }
class View { public string Name { get; set; } }
class SProc { public string Name { get; set; } }


     <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Collection}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate

>  

谢谢GJ

1 个答案:

答案 0 :(得分:1)

我建议创建一个ViewModel来包装主要类别(Tables,Views,StoredProcedures)的项目。这个包装器包含一个分层数据模板从中获取子代的集合。

然后由您决定,如果您还为每种类型(Table,View,StoredProcedure)创建ViewModel,则只返回这些类型的通用ViewModel,或者甚至返回您的基础对象。这个决定很大程度上取决于树中这些项的使用有多复杂。大多数情况下,通用包装器都可以。

Here您将找到有关使用MVVM构建树的简介。