好久没有写博文了,其实也发现没什么可写的,最近又搞起WPF来,其中用到了treeview,有点东西拿来分享一下。
treeview默认是不带checkbox的,但让他带checkbox也很简单,设置一下样式即可,当然这不是难点,也不是重点,重点是checked属性怎么关联数据的问题,笔者也是查阅网上诸多大神的示例,其中就使用了绑带数据源的方式,实现动态改变checked状态,笔者也是在此基础上进行修改,增加了tree的级选模式,即当选中一个节点时,自动选中它的全部子节点及其父节点。效果如图:
关于该大神的示例代码大家可以从这里去看看:http://www.cnblogs.com/zsmhhfy/archive/2013/03/18/2965755.html ,
源码下载 http://files.cnblogs.com/zsmhhfy/TreeViewWithCheckBoxSourceCode.rar
该源代码默认已经实现了选中一个节点,自动选中父节点,但不会选中该节点下面的子节点。使用model中的checked属性遍历设置是实现不了选中子节点的操作,那么笔者就在checkbox上增加一个click事件:
<StackPanel Margin="-2,0,0,0" Orientation="Horizontal" x:Name="staTree">
<CheckBox ToolTip="{Binding ToolTip}" FontSize="14" FontFamily="微软雅黑" Tag="{Binding Children}" IsChecked="{Binding IsChecked, Mode=TwoWay}" Click="treeNode_Click">
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center" Source="{Binding Icon}" ></Image>
<TextBlock Text="{Binding Name}"></TextBlock>
</StackPanel>
</CheckBox>
</StackPanel>
private void treeNode_Click(object sender, RoutedEventArgs e)
{
TreeViewItem item = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
if (item != null)
{
item.Focus();
eachCheckedNode();
e.Handled = true;
}
}
private void eachCheckedNode()
{
if (chktree.SelectedItem != null)
{
TreeModel tree = (TreeModel)chktree.SelectedItem;
tree.SetChildrenChecked(tree.IsChecked);
tree.SetParentChecked(tree.IsChecked);
}
}
以下代码加在model中。
/// <summary>
/// 设置所有子项的选中状态
/// </summary>
/// <param name="isChecked"></param>
public void SetChildrenChecked(bool isChecked)
{
foreach (TreeModel child in Children)
{
child.IsChecked = IsChecked;
child.SetChildrenChecked(IsChecked);
}
}
/// <summary>
/// 设置所属父节点的选中状态
/// </summary>
/// <param name="isChecked"></param>
public void SetParentChecked(bool isChecked)
{
if (Parent != null)
{
if (isChecked && !Parent.IsChecked)
{
Parent.IsChecked = IsChecked;
Parent.SetParentChecked(isChecked);
}
else
{
if (!isChecked && !Parent.getChildrenChecked())
{
Parent.IsChecked = IsChecked;
Parent.SetParentChecked(isChecked);
}
}
}
}
/// <summary>
/// 获取所有子项的选中状态
/// </summary>
/// <return value>true表示有选中的,false表示没有选中的</teturn>
public bool getChildrenChecked()
{
bool value = false;
foreach (TreeModel child in Children)
{
if (child.IsChecked)
{
value = true;
break;
}
}
return value;
}
将原来代码中的checked属性中的级选操作注释,避免重复调用。
这样,treeview就可以级选操作了。
http://blog.youkuaiyun.com/kunoy/article/details/11603933