前段時間在項目開發(fā)中需要用 TreeListView 的功能,于是在網(wǎng)上狂搜一通,倒也找到了幾個小例子,但還是滿足不了我簡單的要求,由于時間緊也只能折中湊合著用了。最近時間比較充裕,把其中的例子整理一下分享給大家。在文章最后部分還有一個沒解決的問題,也希望得到牛人的指點,小弟不勝感激 O(∩_∩)O~ 文章中使用的是msdn提供的示例,源代碼下載 - TreeListView.zip。修改后的程序代碼下載 - TreeListViewSample.zip,修改前后的程序界面如下: 修改前 修改后
1 綁定數(shù)據(jù) 在msdn示例中,數(shù)據(jù)是直接寫在 xaml文件中進(jìn)行綁定的,如下所示: <l:TreeListView> <l:TreeListViewItem> <l:TreeListViewItem.Header> <x:Type TypeName="DependencyObject" /> </l:TreeListViewItem.Header> <l:TreeListViewItem> <l:TreeListViewItem.Header> <x:Type TypeName="Visual" /> </l:TreeListViewItem.Header> ...... <l:TreeListViewItem> <l:TreeListViewItem.Header> <x:Type TypeName="GridViewColumnCollection" /> </l:TreeListViewItem.Header> </l:TreeListViewItem> <l:TreeListViewItem> <l:TreeListViewItem.Header> <x:Type TypeName="GridViewColumnHeaderRole" /> </l:TreeListViewItem.Header> </l:TreeListViewItem> </l:TreeListView>
這種做法的弊端不用多說,在我們實際開發(fā)過程中是絕對不允許的,下面我把它改成了基于MVVM的數(shù)據(jù)綁定方式。首先用 NuGet插件管理引入 MvvmLight,然后在Model中添加Staff類,Staff類中定義了一些在界面上顯示的屬性,在 ViewModel中添加 MainViewModel類,用來生成一些綁定到界面的測試數(shù)據(jù),并將 MainViewModel實例賦值給 MainWindow的 DataContext: MainViewModel vm = new MainViewModel();this.DataContext = vm;
數(shù)據(jù)源準(zhǔn)備完畢,接著就是對界面顯示的改動,將綁定列的集合GridViewColumnCollection 改為下面的代碼: <GridViewColumnCollection x:Key="gvColumns"> <GridViewColumn Header="姓名" CellTemplate="{StaticResource CellTemplate_Name}" Width="100" /> <GridViewColumn Header="年齡" DisplayMemberBinding="{Binding Age}" Width="80" /> <GridViewColumn Header="性別" DisplayMemberBinding="{Binding Sex}" Width="80" /> <GridViewColumn Header="職務(wù)" DisplayMemberBinding="{Binding Duty}" Width="100" /></GridViewColumnCollection>
最后一步,也是最關(guān)鍵的一步是給 TreeListView綁定數(shù)據(jù)源: <l:TreeListView Background="WhiteSmoke" BorderBrush="#FF32C1FF" ItemsSource="{Binding StaffList}"> <l:TreeListView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding StaffList}" /> </l:TreeListView.ItemTemplate></l:TreeListView>
完成以上步驟,運(yùn)行程序即可看到如下界面,動態(tài)創(chuàng)建的數(shù)據(jù)已經(jīng)綁定到 TreeListView:
2 添加滾動條 按說能夠動態(tài)的顯示數(shù)據(jù),主要的功能就算完成了,但在實際開發(fā)中許多細(xì)節(jié)的方面的東西還是需要考慮地,于是,為了 TreeListView能夠更好的在程序中使用,就需要考慮更多的細(xì)節(jié)。運(yùn)行 msdn提供的示例會發(fā)現(xiàn)顯示內(nèi)容超出控件本身的范圍時并沒有滾動條出現(xiàn),下面是 msdn 中 TreeListView的樣式: <Style TargetType="{x:Type l:TreeListView}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type l:TreeListView}"> <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <DockPanel> <GridViewHeaderRowPresenter Columns="{StaticResource gvColumns}" DockPanel.Dock="Top"/> <ItemsPresenter /> </DockPanel> </Border> </ControlTemplate> </Setter.Value> </Setter></Style>
我們可以看到最外層是Border,其內(nèi)部是DockPanel,Panel包含了 GridViewHeaderRowPresenter(頭部)和 ItemsPresenter(內(nèi)容)兩部分。根本就沒有發(fā)現(xiàn) ScrollViewer的影子,不出現(xiàn)滾動條也不奇怪了,下面的代碼給它添加上了ScrollViewer: <Style TargetType="{x:Type l:TreeListView}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type l:TreeListView}"> <Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> <DockPanel> <GridViewHeaderRowPresenter Columns="{StaticResource gvColumns}" DockPanel.Dock="Top"/> <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <ItemsPresenter /> </ScrollViewer> </DockPanel> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter></Style>
這里可能有人會有疑問為什么添加兩個ScrollViewer,只用外層的 ScrollViewer 并把屬性VerticalScrollBarVisibility 設(shè)置為Auto不行嗎?這樣做也是可行的,只是在垂直滾動時列表標(biāo)題行也會跟隨滾動條滾動,而不是固定在頂端。
3 選中、展開節(jié)點 利用第一部分?jǐn)?shù)據(jù)綁定的方式也可以實現(xiàn)自動選中、展開節(jié)點,在 Staff類中添加如下屬性: private bool _IsSelected;private bool _IsExpanded;/// <summary>/// 是否選中/// </summary>public bool IsSelected{ get { return _IsSelected; } set { _IsSelected = value; this.RaisePropertyChanged("IsSelected"); }}/// <summary>/// 是否展開/// </summary>public bool IsExpanded{ get { return _IsExpanded; } set { _IsExpanded = value; this.RaisePropertyChanged("IsExpanded"); }} 然后在 TreeListViewItem樣式中,添加如下代碼即可實現(xiàn)此功能: <Setter Property="IsSelected" Value="{Binding IsSelected}" /><Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
4 鼠標(biāo)滑過改變背景色 對于 TreeListViewItem,在 Template的 ControlTemplate.Triggers中添加如下代碼,即可實現(xiàn)此功能: <Trigger Property="IsMouseOver" Value="true" SourceName="innerBorder"> <Setter Property="Foreground" Value="White"/> <Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/></Trigger>
5 交替行樣式 前面幾部分把修改的主要部分進(jìn)行了介紹,文章最后當(dāng)然是提出那個沒有解決的問題。 當(dāng)看到文章開始部分修改后的程序截圖時,您可能已經(jīng)有怪怪的感覺,怎么行的背景色是這么變化的,雜亂無章,讓它交替改變背景色多好!( ⊙ o ⊙ )是的,我也是想做出那樣的效果,只是沒有能夠找到解決的方法,在此懇請牛人指點一二,多謝 |
|