WPF數(shù)據(jù)綁定在目錄樹構(gòu)造中作用體現(xiàn)
WPF開(kāi)發(fā)工具的使用,為開(kāi)發(fā)人員帶來(lái)了非常大的作用。開(kāi)發(fā)人員在實(shí)際開(kāi)發(fā)編程中,可以輕松靈活的實(shí)現(xiàn)與MAC相媲美的圖形界面。#t#
如果使用了WPF而不使用數(shù)據(jù)綁定(手工在界面和數(shù)據(jù)間進(jìn)行同步),總會(huì)感覺(jué)不值.但是大部分討論WPF數(shù)據(jù)綁定的文章,主題大多集中在ListBox這樣平坦的數(shù)據(jù)集合上,講如何綁定層次結(jié)構(gòu)數(shù)據(jù)的比較少,這里我就通過(guò)一個(gè)簡(jiǎn)單的顯示磁盤目錄樹的例子來(lái)展示如何完成這樣的任務(wù).
WPF數(shù)據(jù)綁定第一步,當(dāng)然是定義要綁定的數(shù)據(jù)類型了.
在目錄樹這個(gè)例子中,每個(gè)TreeViewItem要顯示的數(shù)據(jù)可以用System.IO.DirectoryInfo來(lái)表示,但是這樣做有一個(gè)麻煩:DirectoryInfo只能通過(guò)GetDirectories()方法來(lái)獲取子目錄,但是WPF里的數(shù)據(jù)綁定則更傾向于使用屬性在數(shù)據(jù)間導(dǎo)航,所以為了更方便地使用WPF數(shù)據(jù)綁定,我們最好還是自定義一個(gè)類來(lái)完成這樣的工作:
- using System.Collections.Generic;
- using System.IO;
- namespace WpfApplication1
- {
- class BindDirectory
- {
- public BindDirectory(string
directoryPath) - {
- //正規(guī)化目錄路徑,確保Path以'\\'結(jié)尾
- directoryPathdirectoryPath =
directoryPath.TrimEnd('\\'); - Path = directoryPath + '\\';
- //計(jì)算出目錄名稱(不包含路徑)
- int indexLastSlash = directoryPath.
LastIndexOf('\\'); - if (indexLastSlash >= 0)
- {
- Name = directoryPath.Substring
(indexLastSlash + 1); - }
- else
- {
- Name = directoryPath;
- }
- }
- public string Name
- {
- get;
- private set;
- }
- public string Path
- {
- get;
- private set;
- }
- public IEnumerable< BindDirectory>
Directories - {
- get
- {
- //延遲加載
- if (directories == null)
- {
- directories = new List
< BindDirectory>(); - foreach (string d in Directory.
GetDirectories(Path)) - {
- directories.Add(new
BindDirectory(d)); - }
- }
- return directories;
- }
- }
- List< BindDirectory> directories;
- }
- }
這個(gè)類所作的工作很簡(jiǎn)單,就是正規(guī)化目錄路徑,獲取目錄名稱,以及延遲加載子目錄(以提升性能)的列表,我們的界面也只要求它具有這些功能就行了.
WPF數(shù)據(jù)綁定第二步,創(chuàng)建一個(gè)數(shù)據(jù)提供類(DataProvider)
我們可以在Window的代碼里設(shè)置界面的DataContext,ItemsSource等屬性來(lái)讓界面顯示指定的數(shù)據(jù),也可以構(gòu)造一個(gè)專門提供數(shù)據(jù)的類,完全在界面(XAML)里指定,這里使用的是第二種方法:
- using System.Collections.Generic;
- using System.IO;
- namespace WpfApplication1
- {
- class BindDirectoryList :
List< BindDirectory>- {
- public BindDirectoryList()
- {
- foreach (var drive in
DriveInfo.GetDrives())- {
- Add(new BindDirectory(drive.
RootDirectory.FullName));- }
- }
- }
- }
這個(gè)類就更簡(jiǎn)單了,僅僅是在創(chuàng)建的時(shí)候加載所有的磁盤的根目錄.
WPF數(shù)據(jù)綁定第三步,設(shè)計(jì)用戶界面
只需要在Window中添加一個(gè)TreeView,然后修改幾行代碼,就能輕松地顯示我們的數(shù)據(jù)了:
- < !--xml:sample這一行用來(lái)引入
我們自己代碼的命名空間-->- < Window x:Class="WpfApp
lication1.Window1"- xmlns="http://schemas.
microsoft.com/winfx/2006/
xaml/presentation"- xmlns:x="http://schemas.
microsoft.com/winfx/2006/xaml"- xmlns:sample="clr-namespace:
WpfApplication1"- Title="Window1" Height="300"
Width="300">- < Window.Resources>
- < !--引入我們自己的數(shù)據(jù)提供對(duì)象-->
- < ObjectDataProvider x:Key="drives"
ObjectType="{x:Type sample:
BindDirectoryList}" />- < !--設(shè)置如何顯示數(shù)據(jù),以及如何獲
取下一級(jí)數(shù)據(jù)的列表-->- < HierarchicalDataTemplate x:Key=
"itemTemplate" DataType="{x:Type
sample:BindDirectory}" ItemsSource=
"{Binding Directories}">- < TextBlock Text="{Binding Name}" />
- < /HierarchicalDataTemplate>
- < /Window.Resources>
- < TreeView ItemsSource="{Binding
Source={StaticResource drives}}"- ItemTemplate="{StaticResource
itemTemplate}" >- < /TreeView>
- < /Window>
這里我們?cè)赬AML里定義了一個(gè)drives對(duì)象,它的類型為BindDirectoryList,創(chuàng)建時(shí)會(huì)自動(dòng)加載磁盤的根目錄;
我們?cè)赪PF數(shù)據(jù)綁定中還定義了一個(gè)針對(duì)BindDirectory類型的層次型數(shù)據(jù)模板itemsTemplate,指定了要獲取此類型的數(shù)據(jù)的子數(shù)據(jù)需要通過(guò)Directories屬性,并且告訴WPF用一個(gè)TextBlock來(lái)顯示它的名稱.
最后,我們?cè)O(shè)置一下TreeView的ItemsSource和ItemTemplate就完成工作了.