首先来谈一下实现将自定义的类TreeMode绑定到TreeView控件上的一个基本的思路,由于每一个节点都要包含很多自定义的一些属性信息,因此我们需要将该类TreeMode进行封装,TreeView的每一个节点的类型都是TreeMode,我们还定义一些Children属性,Parent属性用于定义当前节点的子节点和父节点,当然还定义了一些常见的Name、ToolTip、ID、IsExpand、IsChecked(主要是在每一个节点前面添加了一个CheckBox)等属性,另外的一些属性就是具体需要使用的一些属性,并且该类还实现了INotifyPropertyChanged接口,从而使属性发生改变的时候提供通知,从而更新到UI上面。
另外一部分就是前台代码部分,这里贴出部分代码:
<TreeView.ItemTemplate> <!--ItemsSource指定该类数据的子集,即下一层(HierarchicalDataTemplate.ItemTemplate)显示那些数据--> <HierarchicalDataTemplate DataType="{x:Type localex:TreeMode}" ItemsSource="{Binding Children}"> <Border Name="fatherNod" MouseLeftButtonDown="fatherNod_MouseLeftButtonDown"> <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource sampleContextMenu1}" ToolTip="{Binding ToolTip}"> <CheckBox Tag="{Binding Children}" IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0,5,2,0" Checked="CheckBox_Checked" /> <Image VerticalAlignment="Center" Source="{Binding Icon}"/> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding CameraName}" HorizontalAlignment="Center" Width="550"/> <TextBox x:Name="renametextbox" Text="{Binding CameraName}" HorizontalAlignment="Center" Margin="0,-20,0,0" Width="550" Visibility="Collapsed" LostFocus="renametextbox_LostFous"/> </StackPanel> </StackPanel> </Border> <!--采用级联的数据模板的方式进行数据绑定--> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate> <Border Name="sonNod" MouseLeftButtonDown="sonNod_MouseLeftButtonDown"> <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource sampleContextMenu2}" ToolTip="{Binding ToolTip}"> <CheckBox Tag="{Binding Children}" IsChecked="{Binding IsChecked, Mode=TwoWay}" Margin="0,5,2,0" Checked="CheckBox_Checked"/> <Image VerticalAlignment="Center" Source="{Binding Icon}"/> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding CameraInstallAdress}" HorizontalAlignment="Center" Width="450"/> <TextBox x:Name="renametextbox" Text="{Binding CameraName}" HorizontalAlignment="Center" Margin="0,-20,0,0" Width="460" Height="40" Visibility="Collapsed" LostFocus="renametextbox_LostFous"/> </StackPanel> </StackPanel> </Border> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </TreeView.ItemTemplate>
前台代码的话采用级联的数据模板来进行绑定,绑定的目标是TreeMode,其它的一些控件分别绑定到对应的属性上面,这里需要特别说明一下,ItemsSource指定该类数据的子集,即下一层(HierarchicalDataTemplate.ItemTemplate)显示那些数据,这里需要特别注意。在完成了这些基本的操作之后,就是后台代码添加数据源。
这里我是通过两种方式来添加数据源的,第一种读取数据库之后将数据放到泛型List中,采用这种方式的时候会出现界面卡死的情况,这里我们定义了一个数据源属性。
public List<TreeMode> ItemsSourceData { get { return itemsSourceData; } set { itemsSourceData = value; this.AllNodesTreeView.ItemsSource = itemsSourceData; } }
我们将从数据库中读取到的数据封装在一个myList=List<TreeMode>中,这里需要特别注意的是每次必须是先将this.ItemsSourceData=null,然后再将this.ItemsSource Data=myList,才能更新到UI界面上面,而且当增加项或者删除项的时候,界面会卡死掉,反应的速度特别慢,之后结合之前的一些开发经历,将List<TreeMode>改为Observ ableCollection<TreeMode>,并且在赋值的时候只需this.ItemsSourceData=myList就可以了,不用再this.ItemsSourceData=null,当然所有的List<TreeMode>必须要设置为ObservableCollection<TreeMode> ,这里就体现了两者的区别,官方的解释是表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。当然我们在自己写类的时候也可以继承INotifyPropertyChanged接口,然后 定义 public event PropertyChangedEventHandler PropertyChanged事件,然后再实现PropertyChanged事件。