WPF TreeView DataTable 绑定 实现无限层过滤

WPF TreeView DataTable 绑定 实现无限层过滤

时间:2012-02-24 19:48 来源:博客园 作者:sliphades 点击: 166次
WPF 树绑定,确实不容易,如果思路停留在以前WinForm,Asp.net 上面就会很吃力,要转变为MVVM思想,开发起来才会得心应手,我写这篇文章的目的不在于建议使用DataTable 直接来绑定TreeView,而是想通过此文给予误入WPF误区的青年(just like me)给予一些帮助,最终我还是使用MVVM模式来完成了WPF中TreeView 的绑定。 废话不
  

WPF 树绑定,确实不容易,如果思路停留在以前WinForm,Asp.net 上面就会很吃力,要转变为MVVM思想,开发起来才会得心应手,我写这篇文章的目的不在于建议使用DataTable 直接来绑定TreeView,而是想通过此文给予误入WPF误区的青年(just like me)给予一些帮助,最终我还是使用MVVM模式来完成了WPF中TreeView 的绑定。

废话不多说,表数据如下

F_IDF_ParentIDF_NameF_Remark
2b632e6f-358c-4ba7-bdd9-fb0777ee6695NULL学历描述人员学历
3a809712-4773-4fcf-b568-fcd9c52dbe562b632e6f-358c-4ba7-bdd9-fb0777ee6695本科NULL
934d23ca-2c56-4108-971f-79a786e4db712b632e6f-358c-4ba7-bdd9-fb0777ee6695专科NULL
7a9b3891-e5d9-4649-824d-984db88d9ad42b632e6f-358c-4ba7-bdd9-fb0777ee6695高中NULL

   

主要功能实现用户输入关键字,TreeView 根据关键字(按照树节点名称拼音)过滤树节点。

取出表数据存放于DataSet中的DataTable里面,我们要设置其关系(当让如果你用Typed DataSet 可以直接用IDE画出来),让系统知道这个是个树型结构。

核心代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace WPFTreeViewDataTableDemo
{
/// <summary>
/// WPF TreeView DataTable 绑定对象
/// </summary>
public class WPFTreeViewBind
{
/// <summary>
/// 主要是用作 TreeView 数据源显示
/// </summary>
public DataView RootNodes
{
set;
get;
}

String BaseFilter
{
get;
set;
}

public String FilterColumn
{
get;
set;
}

public Predicate<String> CustomFiler
{
get;
set;
}

/// <summary>
/// 组织 DataTable 形成树状结构
/// </summary>
/// <param name="TreeDB">数据源DataSet</param>
/// <param name="IDColumn">ID列</param>
/// <param name="ParentColumn">父ID列</param>
/// <param name="ParentIDFilter">过滤字符(满足我们实体表中F_ParentID =1 或者 -1 或者 "" 等情况)</param>
public void InitTreeViewDataSet(DataSet TreeDB, String IDColumn, String ParentColumn, String RootParentID)
{

//TreeDB.Tables[0].TableName = "Master";
///添加一个逻辑列,用来过滤
TreeDB.Tables["Master"].Columns.Add("Flag", typeof(bool));

//添加父子关系(注意添加一列逻辑列用来过滤使用)两个条件作为 AND 使用关于表关系可以参考DataTable Relations
TreeDB.Relations.Add("TreeChild",
new DataColumn[] { TreeDB.Tables["Master"].Columns[IDColumn], TreeDB.Tables["Master"].Columns["Flag"] },
new DataColumn[] { TreeDB.Tables["Master"].Columns[ParentColumn], TreeDB.Tables["Master"].Columns["Flag"] }, false);

//再次添加父子关系,不关联逻辑列
TreeDB.Relations.Add("TreeParentChild",
new DataColumn[] { TreeDB.Tables["Master"].Columns[IDColumn], },
new DataColumn[] { TreeDB.Tables["Master"].Columns[ParentColumn], }, false);

//我们要显示的就是RootNode
RootNodes = TreeDB.Tables["Master"].DefaultView;

//初始化DataTable 逻辑列
foreach (DataRow dr in RootNodes.Table.Rows)
{
dr.SetField("Flag", true);
}
//初始化过滤列模式(用于完成满足我们实体表中F_ParentID =1 或者 -1 或者 "" 等情况)
String TypeOFLink = String.Empty;
if (String.Compare(RootParentID, "NULL", false) == 0)
{
TypeOFLink = " Is ";
}
else
{
TypeOFLink = " = ";
}
BaseFilter = "(" + ParentColumn + TypeOFLink + RootParentID + ") " + " AND (Flag = True)";

RootNodes.RowFilter = BaseFilter;
}

/// <summary>
/// 设置过滤器(利用DataView 过滤功能)
/// </summary>
/// <param name="_filterString">过滤关键字</param>
public void SetFilter()
{

foreach (DataRow dr in RootNodes.Table.Rows)
{
if (String.IsNullOrEmpty(FilterColumn))
{
dr.SetField("Flag", true);
}
else
{
dr.SetField("Flag", false);
}
}

foreach (DataRow dr in RootNodes.Table.Rows)
{
if (this.CustomFiler(dr[FilterColumn].ToString()))
{
dr.SetField("Flag", false);
}
}

foreach (DataRow dr in RootNodes.Table.Rows)
{
if (this.CustomFiler(dr[FilterColumn].ToString()))
{
dr.SetField("Flag", true);

this.SetParent(dr, true);

}
}

RootNodes.RowFilter = BaseFilter;
}
/// <summary>
/// 设置父数据
/// </summary>
/// <param name="dr"></param>
/// <param name="p"></param>
private void SetParent(DataRow dr, bool p)
{
if (dr.GetParentRow("TreeParentChild") != null)
{
dr.GetParentRow("TreeParentChild").SetField("Flag", p);
SetParent(dr.GetParentRow("TreeParentChild"), p);
}
}
}
}

前台调用

using System;
using System.Windows.Controls;
using WPFTreeViewDataTableDemo.DB;
using WPFTreeViewDataTableDemo.DB.DatabaseDataSetTableAdapters;
using System.Data;

namespace WPFTreeViewDataTableDemo
{
/// <summary>
/// demoMain.xaml 的交互逻辑
/// </summary>
public partial class demoMain : Page
{
WPFTreeViewBind WVB;
DataSet OperatorDataSet;
public demoMain()
{
InitializeComponent();
T_BaseCodeTableAdapter filler = new T_BaseCodeTableAdapter();
DatabaseDataSet DB = new DatabaseDataSet();
filler.Fill(DB.T_BaseCode);
WVB = new WPFTreeViewBind();
//此处我使用强类型仅作为一个演示,操作普通类型 DataTable.当然你可以直接返回你类型化的DataSet(DB.T_BaseCode)

DataTable OperatorTabel = DB.T_BaseCode.DefaultView.ToTable("Master");
OperatorDataSet = new DataSet();
OperatorDataSet.Tables.Add(OperatorTabel);

WVB.InitTreeViewDataSet(OperatorDataSet, "F_ID", "F_ParentID", "NULL");
WVB.FilterColumn = "F_Name";
WVB.CustomFiler = CustomFilter;
tree.DataContext = WVB;


}
String FilterString;
Boolean CustomFilter(object sender)
{
return sender.ToString().GetChineseSpell(false).Contains(FilterString);
}

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox Tb =sender as TextBox;
FilterString= Tb.Text.Trim();
WVB.SetFilter();

}
}
}

XAML

<Page x:Class="WPFTreeViewDataTableDemo.demoMain"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable
="d"
d:DesignHeight
="300" d:DesignWidth="300"
Title
="demoMain">
<Grid>
<StackPanel Orientation="Vertical">
<GroupBox Header="检索过滤">
<TextBox TextChanged="TextBox_TextChanged"></TextBox>
</GroupBox>
<TreeView Name="tree" ItemsSource="{Binding RootNodes }">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding TreeChild}">
<TextBlock Text="{Binding F_Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

</StackPanel>
</Grid>
</Page>

最终实现如图:

 

未过滤

已过滤

 

源码下载

  本文来自sliphades的博客,原文地址:http://www.cnblogs.com/peerlesssoul/articles/2350085.html

  

转载于:https://www.cnblogs.com/hdxhan/archive/2012/02/26/2369119.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值