前段時(shí)間在項(xiàng)目開(kāi)發(fā)中需要用 TreeListView 的功能,于是在網(wǎng)上狂搜一通,倒也找到了幾個(gè)小例子,但還是滿(mǎn)足不了我簡(jiǎn)單的要求,由于時(shí)間緊也只能折中湊合著用了。最近時(shí)間比較充裕,把其中的例子整理一下分享給大家。在文章最后部分還有一個(gè)沒(méi)解決的問(wèn)題,也希望得到牛人的指點(diǎn),小弟不勝感激 O(∩_∩)O~ 文章中使用的是msdn提供的示例,源代碼下載 - TreeListView.zip。修改后的程序代碼下載 - TreeListViewSample.zip,修改前后的程序界面如下: 修改前 修改后
1 綁定數(shù)據(jù) 在msdn示例中,數(shù)據(jù)是直接寫(xiě)在 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>
這種做法的弊端不用多說(shuō),在我們實(shí)際開(kāi)發(fā)過(guò)程中是絕對(duì)不允許的,下面我把它改成了基于MVVM的數(shù)據(jù)綁定方式。首先用 NuGet插件管理引入 MvvmLight,然后在Model中添加Staff類(lèi),Staff類(lèi)中定義了一些在界面上顯示的屬性,在 ViewModel中添加 MainViewModel類(lèi),用來(lái)生成一些綁定到界面的測(cè)試數(shù)據(jù),并將 MainViewModel實(shí)例賦值給 MainWindow的 DataContext: MainViewModel vm = new MainViewModel();this.DataContext = vm;
數(shù)據(jù)源準(zhǔn)備完畢,接著就是對(duì)界面顯示的改動(dòng),將綁定列的集合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)行程序即可看到如下界面,動(dòng)態(tài)創(chuàng)建的數(shù)據(jù)已經(jīng)綁定到 TreeListView:
2 添加滾動(dòng)條 按說(shuō)能夠動(dòng)態(tài)的顯示數(shù)據(jù),主要的功能就算完成了,但在實(shí)際開(kāi)發(fā)中許多細(xì)節(jié)的方面的東西還是需要考慮地,于是,為了 TreeListView能夠更好的在程序中使用,就需要考慮更多的細(xì)節(jié)。運(yùn)行 msdn提供的示例會(huì)發(fā)現(xiàn)顯示內(nèi)容超出控件本身的范圍時(shí)并沒(méi)有滾動(dòng)條出現(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)容)兩部分。根本就沒(méi)有發(fā)現(xiàn) ScrollViewer的影子,不出現(xiàn)滾動(dòng)條也不奇怪了,下面的代碼給它添加上了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>
這里可能有人會(huì)有疑問(wèn)為什么添加兩個(gè)ScrollViewer,只用外層的 ScrollViewer 并把屬性VerticalScrollBarVisibility 設(shè)置為Auto不行嗎?這樣做也是可行的,只是在垂直滾動(dòng)時(shí)列表標(biāo)題行也會(huì)跟隨滾動(dòng)條滾動(dòng),而不是固定在頂端。
3 選中、展開(kāi)節(jié)點(diǎn) 利用第一部分?jǐn)?shù)據(jù)綁定的方式也可以實(shí)現(xiàn)自動(dòng)選中、展開(kāi)節(jié)點(diǎn),在 Staff類(lèi)中添加如下屬性: private bool _IsSelected;private bool _IsExpanded;/// <summary>/// 是否選中/// </summary>public bool IsSelected{ get { return _IsSelected; } set { _IsSelected = value; this.RaisePropertyChanged("IsSelected"); }}/// <summary>/// 是否展開(kāi)/// </summary>public bool IsExpanded{ get { return _IsExpanded; } set { _IsExpanded = value; this.RaisePropertyChanged("IsExpanded"); }} 然后在 TreeListViewItem樣式中,添加如下代碼即可實(shí)現(xiàn)此功能: <Setter Property="IsSelected" Value="{Binding IsSelected}" /><Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
4 鼠標(biāo)滑過(guò)改變背景色 對(duì)于 TreeListViewItem,在 Template的 ControlTemplate.Triggers中添加如下代碼,即可實(shí)現(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)然是提出那個(gè)沒(méi)有解決的問(wèn)題。 當(dāng)看到文章開(kāi)始部分修改后的程序截圖時(shí),您可能已經(jīng)有怪怪的感覺(jué),怎么行的背景色是這么變化的,雜亂無(wú)章,讓它交替改變背景色多好!( ⊙ o ⊙ )是的,我也是想做出那樣的效果,只是沒(méi)有能夠找到解決的方法,在此懇請(qǐng)牛人指點(diǎn)一二,多謝 |
|
來(lái)自: 牛人的尾巴 > 《treeview控件》