WPF數據綁定在目錄樹構造中作用體現
WPF開發工具的使用,為開發人員帶來了非常大的作用。開發人員在實際開發編程中,可以輕松靈活的實現與MAC相媲美的圖形界面。#t#
如果使用了WPF而不使用數據綁定(手工在界面和數據間進行同步),總會感覺不值.但是大部分討論WPF數據綁定的文章,主題大多集中在ListBox這樣平坦的數據集合上,講如何綁定層次結構數據的比較少,這里我就通過一個簡單的顯示磁盤目錄樹的例子來展示如何完成這樣的任務.
WPF數據綁定第一步,當然是定義要綁定的數據類型了.
在目錄樹這個例子中,每個TreeViewItem要顯示的數據可以用System.IO.DirectoryInfo來表示,但是這樣做有一個麻煩:DirectoryInfo只能通過GetDirectories()方法來獲取子目錄,但是WPF里的數據綁定則更傾向于使用屬性在數據間導航,所以為了更方便地使用WPF數據綁定,我們最好還是自定義一個類來完成這樣的工作:
- using System.Collections.Generic;
- using System.IO;
- namespace WpfApplication1
- {
- class BindDirectory
- {
- public BindDirectory(string
directoryPath) - {
- //正規化目錄路徑,確保Path以'\\'結尾
- directoryPathdirectoryPath =
directoryPath.TrimEnd('\\'); - Path = directoryPath + '\\';
- //計算出目錄名稱(不包含路徑)
- 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;
- }
- }
這個類所作的工作很簡單,就是正規化目錄路徑,獲取目錄名稱,以及延遲加載子目錄(以提升性能)的列表,我們的界面也只要求它具有這些功能就行了.
WPF數據綁定第二步,創建一個數據提供類(DataProvider)
我們可以在Window的代碼里設置界面的DataContext,ItemsSource等屬性來讓界面顯示指定的數據,也可以構造一個專門提供數據的類,完全在界面(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));- }
- }
- }
- }
這個類就更簡單了,僅僅是在創建的時候加載所有的磁盤的根目錄.
WPF數據綁定第三步,設計用戶界面
只需要在Window中添加一個TreeView,然后修改幾行代碼,就能輕松地顯示我們的數據了:
- < !--xml:sample這一行用來引入
我們自己代碼的命名空間-->- < 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>
- < !--引入我們自己的數據提供對象-->
- < ObjectDataProvider x:Key="drives"
ObjectType="{x:Type sample:
BindDirectoryList}" />- < !--設置如何顯示數據,以及如何獲
取下一級數據的列表-->- < 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>
這里我們在XAML里定義了一個drives對象,它的類型為BindDirectoryList,創建時會自動加載磁盤的根目錄;
我們在WPF數據綁定中還定義了一個針對BindDirectory類型的層次型數據模板itemsTemplate,指定了要獲取此類型的數據的子數據需要通過Directories屬性,并且告訴WPF用一個TextBlock來顯示它的名稱.
最后,我們設置一下TreeView的ItemsSource和ItemTemplate就完成工作了.