WPF中TreeView控制元件資料繫結和後臺動態新增資料
阿新 • • 發佈:2019-01-06
資料繫結:
TreeView資料繫結需要使用層次結構資料模板(HierarchicalDataTemplate)來顯示分層資料。XAML程式碼如下:
<TreeView Name="chapterTree" Grid.Column="0"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Path=ChildNodes}"> <StackPanel> <Label Content="{Binding Path=NodeName}"/> </StackPanel> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView>
其中,ItemsSource繫結的物件ChildNodes應該是一個集合型別:List<TreeNode>,Label中繫結的是TreeNode的NodeName屬性,TreeNode類定義如下所示:
publicclass TreeNode { public int NodeID { get; set; } public int ParentID { get; set; } public string NodeName { get; set; } public List<TreeNode> ChildNodes { get; set; } public TreeNode() { ChildNodes = new List<TreeNode>(); } }
因為是樹形結構,因此TreeNode需要有NodeID屬性和ParentID屬性,即某個樹節點node本身的ID和它所屬的父節點的ID。以目錄為例,則xaml.cs中的程式碼如下。首先是寫入了資料,在我實際專案中,這些資料是從DB中查詢的,這裡為了簡化,直接Input資料了。
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); InputData(); chapterTree.ItemsSource = getNodes(0, nodes); } private List<TreeNode> nodes; private void InputData() { nodes = new List<TreeNode>() { new TreeNode(){ParentID=0, NodeID=1, NodeName = "Chapter1" }, new TreeNode(){ParentID=0, NodeID=2, NodeName="Chapter2"}, new TreeNode(){ParentID=0,NodeID=3, NodeName="Chapter3"}, new TreeNode(){ParentID=1, NodeID=4, NodeName="Section1.1"}, new TreeNode(){ParentID=1, NodeID=5, NodeName="Section1.2"}, new TreeNode(){ParentID=2, NodeID=6, NodeName="Section2.1"}, new TreeNode(){ParentID=3, NodeID=7, NodeName="Section3.1"}, new TreeNode(){ParentID=6, NodeID=8, NodeName="SubSection2.1.1"}, new TreeNode(){ParentID=6, NodeID=9, NodeName="SubSection2.1.2"}, new TreeNode(){ParentID=2, NodeID=10,NodeName="Section2.2"}, new TreeNode(){ParentID=3, NodeID=11, NodeName="Section3.2"} }; } private List<TreeNode> getNodes(int parentID, List<TreeNode> nodes) { List<TreeNode> mainNodes = nodes.Where(x => x.ParentID == parentID).ToList(); List<TreeNode> otherNodes = nodes.Where(x => x.ParentID != parentID).ToList(); foreach (TreeNode node in mainNodes) node.ChildNodes = getNodes(node.NodeID, otherNodes); return mainNodes; } }
需要注意的就是NodeID是不斷增加的,每個節點都有自己的ID,而其ParentID就看它是屬於哪個父節點的了。getNodes()是一個遞迴方法,就是不斷讀取某個節點的子節點。執行結果如圖所示:
後臺動態新增TreeView:
一開始,沒用資料繫結,就直接在xaml.cs中使用treeview,雖然後來用了資料繫結之後發現還是繫結更方便,但是這種在後臺構建treeview的方法沒準哪天也能用到,就記錄一下吧。
XAML檔案,使用一個TreeView控制元件
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="60*"/> <ColumnDefinition Width="100*"/> </Grid.ColumnDefinitions> <TreeView Name="chapterTree" Grid.Column="0"/> </Grid>
XAML.CS檔案,同樣使用遞迴方法,就是不斷的新建treeviewitem控制元件。
public partial class DynamicTreeView : Window { public DynamicTreeView() { InitializeComponent(); InputData(); ShowTreeView(); } private List<TreeNode> nodes; private void InputData() { nodes = new List<TreeNode>() { new TreeNode(){ParentID=0, NodeID=1, NodeName = "Chapter1" }, new TreeNode(){ParentID=0, NodeID=2, NodeName="Chapter2"}, new TreeNode(){ParentID=0,NodeID=3, NodeName="Chapter3"}, new TreeNode(){ParentID=1, NodeID=4, NodeName="Section1.1"}, new TreeNode(){ParentID=1, NodeID=5, NodeName="Section1.2"}, new TreeNode(){ParentID=2, NodeID=6, NodeName="Section2.1"}, new TreeNode(){ParentID=3, NodeID=7, NodeName="Section3.1"}, new TreeNode(){ParentID=6, NodeID=8, NodeName="SubSection2.1.1"}, new TreeNode(){ParentID=6, NodeID=9, NodeName="SubSection2.1.2"}, new TreeNode(){ParentID=2, NodeID=10,NodeName="Section2.2"}, new TreeNode(){ParentID=3, NodeID=11, NodeName="Section3.2"} }; } private void ShowTreeView() { TreeViewItem tv1 = new TreeViewItem(); chapterTree.Items.Add(tv1); GetNodes(0, tv1); } private void GetNodes(int parentID, TreeViewItem tv) { List<TreeNode> mainNodes = nodes.Where(x => x.ParentID == parentID).ToList(); foreach(var item in mainNodes) { TreeViewItem tv1 = new TreeViewItem(); tv1.Header = item.NodeName; tv.Items.Add(tv1); GetNodes(item.NodeID, tv1); } } }
執行圖:總歸是沒有databinding方便。剛開始學習WPF,一開始沒想過要用資料繫結,總感覺只要能實現自己想要的東西就可以了,不用管實現過程,後來使用了之後發現,使用資料繫結構建MVVM架構的應用還是挺好的。