在MOSS2007企业版里,默认提供了很多的过滤器,但是没有一种过滤器可以实现事先设定过滤条件,比如选择当前列表栏作为筛选条件,然后输入对应值,为了满足需求,使用了IFilterProvider接口实现一个Web部件。
可以实现的功能:
可以实现多条件候选值下的单一条件过滤。
可以根据当前连接部件的视图自动适应栏,不需要使用者自己干预。
前期的知识准备:
需要有基本的Web部件的制作部署知识,需要了解Web部件连接的知识背景,这点在WSS SDK里写的很清楚,这个Web部件也是基于SDK写出来的。
MOSS2007使用了新的接口,所以老的接口不在赞成使用,并且编译过程中会出现如下警告:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
但是本文为了兼容性,还是使用了老的接口版本。标准的IFilterProvider必须继承6个接口,但是有一些接口是可选的,所以我在这里省却一个。
using
System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;
namespace MyCompany.Management.Employees
{
[Guid( " 990c2459-2ec6-4794-931d-1e1a67acd723 " )]
public class SqlFilter :WebPart, IFilterProvider
{
#region Web控件
private DropDownList ddl;
private Button btn_setfilter;
private Label lb_msg;
private TextBox tb_input;
private Button btn_clearfilter;
#endregion
#region 控制变量
private bool isConnected;
private string consumername;
private bool isClearFilterClicked;
private bool isSetFilterClicked;
private string errormsg;
/// <summary>
/// 存储列表的域,也就是数据库表中的列
/// </summary>
private string [] fieldList = null ;
/// <summary>
/// 存储列表域的显示名称
/// </summary>
private string [] fielddspList = null ;
/// <summary>
/// 下拉列表设定的过滤条件
/// </summary>
private string filtercondition = string .Empty;
/// <summary>
/// 过滤条件表达式
/// </summary>
private string filterExp;
/// <summary>
/// 保存域的视图状态
/// </summary>
private string dropdownlistVK = " FieldsList " ;
#endregion
#region IFilterProvider事件
/// <summary>
/// FilterProvider的事件
/// </summary>
public event SetFilterEventHandler SetFilter;
public event NoFilterEventHandler NoFilter;
public event ClearFilterEventHandler ClearFilter;
#endregion
#region 重写的接口方法
/// <summary>
/// 注册窗体
/// </summary>
public override void EnsureInterfaces()
{
try
{
// 功能类似于win32中的窗体注册
RegisterInterface( " myFilterProvider " ,
InterfaceTypes.IFilterProvider,
WebPart.LimitOneConnection,
ConnectionRunAt.Server,
this , "" , " 将过滤器提供给 " , " 过滤器 " , true );
}
catch (Exception ee)
{
errormsg = ee.ToString();
WriteLog(ee.ToString());
}
}
/// <summary>
/// 重写CanRunat方法
/// 在web part被重写之前通知asp.net基础结构
/// 检查欲重写的web part是否可以运行在当前配置之上
/// </summary>
/// <returns></returns>
public override ConnectionRunAt CanRunAt()
{
return ConnectionRunAt.Server;
}
/// <summary>
/// 获得Consumer一端的信息,
/// 通知此web part在预重写阶段
/// 已连接。
///
/// </summary>
/// <param name="interfaceName"> 指定的接口名称和RegisterInterface
/// 中的名称保持一致 </param>
/// <param name="connectedPart"> 连接上的web part </param>
/// <param name="connectedInterfaceName"></param>
/// <param name="runAt"></param>
public override void PartCommunicationConnect( string interfaceName,
Microsoft.SharePoint.WebPartPages.WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
{
try
{
if (interfaceName == " myFilterProvider " )
{
isConnected = true ;
consumername = connectedPart.Title;
}
}
catch (Exception ee)
{
lb_msg.Text = ee.ToString();
WriteLog(ee.ToString());
}
}
/// <summary>
/// 通信的主要展开点
/// 在这里可以触发
/// SetFilter
/// NoFilter
/// ClearFilter
/// 事件,可以按照需要来选择。
/// </summary>
public override void PartCommunicationMain()
{
int i = 0 ;
EnsureChildControls();
try
{
if (isConnected)
{
// 在这里设置过滤条件
// 过滤条件的格式为
// "FieldLabel"+{1
.n}+"="+列名+"&"+"FieldValue"+{1
.n}+"="+列值
if (SetFilter != null && isSetFilterClicked)
{
// 匹配列
if (fieldList.Length == 0 )
lb_msg.Text = " 列数为0,不能筛选 " ;
else
for (; i < fieldList.Length; i ++ )
if (fielddspList[i] == ddl.SelectedItem.Text)
break ;
if (tb_input.Text != null )
filterExp = " FilterField1 " + " = " + fieldList[i] +
" & " +
" FilterValue1 " + " = " + tb_input.Text;
SetFilterEventArgs sea = new SetFilterEventArgs();
sea.FilterExpression = filterExp;
SetFilter( this , sea);
}
else if (ClearFilter != null && isClearFilterClicked)
{
ClearFilter( this , new EventArgs());
isClearFilterClicked = false ;
for (i = 0 ; i < fieldList.Length; i ++ )
fieldList[i] = fielddspList[i] = String.Empty;
}
else
if (NoFilter != null )
NoFilter( this , new EventArgs());
}
}
catch (Exception ee)
{
lb_msg.Text = ee.ToString() + " || 当前的i值 " + i;
WriteLog(ee.ToString());
}
}
/// <summary>
/// 这个事件由Consumer的PartCommunicationInit触发,
/// 作用是 接受由Consumer可能发出的一些参数列表,比如列表的栏名和显示名
/// </summary>
/// <param name="sender"></param>
/// <param name="filterConsumerInitEventArgs"></param>
public void FilterConsumerInit( object sender,
FilterConsumerInitEventArgs filterConsumerInitEventArgs)
{
if (filterConsumerInitEventArgs.FieldList != null )
fieldList = filterConsumerInitEventArgs.FieldList;
else
fieldList = null ;
if (filterConsumerInitEventArgs.FieldDisplayList != null )
fielddspList = filterConsumerInitEventArgs.FieldDisplayList;
else
fielddspList = null ;
if (ddl != null )
if (ddl.Items.Count == 0 && fieldList != null )
{
for ( int i = 0 ; i < fieldList.Length; i ++ )
ddl.Items.Add( new ListItem(fielddspList[i], fieldList[i]));
}
}
#endregion
protected override void RenderWebPart(HtmlTextWriter output)
{
if ( ! isConnected)
output.Write( " 请选择一个列表作为Consumer! " );
else
{
if (ddl.Items.Count == 0 && fieldList != null )
{
for ( int i = 0 ; i < fieldList.Length; i ++ )
ddl.Items.Add( new ListItem(fielddspList[i], fieldList[i]));
}
ddl.RenderControl(output);
tb_input.RenderControl(output);
btn_setfilter.RenderControl(output);
lb_msg.RenderControl(output);
btn_clearfilter.RenderControl(output);
}
}
protected override void CreateChildControls()
{
ddl = new DropDownList();
ddl.AutoPostBack = true ;
ddl.ID = " ddl " ;
btn_setfilter = new Button();
btn_clearfilter = new Button();
btn_clearfilter.Text = " 清除结果 " ;
lb_msg = new Label();
// if (ViewState[dropdownlistVK] == null && fieldList.Length != 0)
// {
// string dropdown = ViewState[dropdownlistVK];
// for (int i = 0; i < fieldList.Length; i++)
// {
// ddl.Items.Add(new ListItem(fielddspList[i], fieldList[i]));
// if (i < fieldList.Length - 1)
// ViewState[dropdownlistVK] += ddl.Items[i].Value;
// }
// }
btn_setfilter.Click += new EventHandler(btn_Click);
btn_clearfilter.Click += new EventHandler(btn_clearfilter_Click);
ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
tb_input = new TextBox();
// 设置文本框响应回车事件
tb_input.Attributes.Add( " onkeypress " , " <script language='javascript'>document.all. " + tb_input.ClientID + " .click;</script> " );
btn_setfilter.Text = " 提交 " ;
Controls.Add(ddl);
Controls.Add(tb_input);
Controls.Add(btn_setfilter);
Controls.Add(btn_clearfilter);
Controls.Add(lb_msg);
}
void btn_clearfilter_Click( object sender, EventArgs e)
{
isClearFilterClicked = true ;
}
void btn_Click( object sender, EventArgs e)
{
isSetFilterClicked = true ;
}
void ddl_SelectedIndexChanged( object sender, EventArgs e)
{
filtercondition = ddl.SelectedItem.Text;
}
private void WriteLog( string log)
{
string path = @" /log.txt " ;
if ( ! File.Exists(path))
using (StreamWriter sw = File.CreateText(path))
{
sw.Write(String.Format( " {0}: {1} " ,DateTime.Now,log));
}
using (StreamWriter sw = File.AppendText(path))
{
sw.Write(String.Format( " {0}: {1} " , DateTime.Now, log));
}
}
}
}
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;
namespace MyCompany.Management.Employees
{
[Guid( " 990c2459-2ec6-4794-931d-1e1a67acd723 " )]
public class SqlFilter :WebPart, IFilterProvider
{
#region Web控件
private DropDownList ddl;
private Button btn_setfilter;
private Label lb_msg;
private TextBox tb_input;
private Button btn_clearfilter;
#endregion
#region 控制变量
private bool isConnected;
private string consumername;
private bool isClearFilterClicked;
private bool isSetFilterClicked;
private string errormsg;
/// <summary>
/// 存储列表的域,也就是数据库表中的列
/// </summary>
private string [] fieldList = null ;
/// <summary>
/// 存储列表域的显示名称
/// </summary>
private string [] fielddspList = null ;
/// <summary>
/// 下拉列表设定的过滤条件
/// </summary>
private string filtercondition = string .Empty;
/// <summary>
/// 过滤条件表达式
/// </summary>
private string filterExp;
/// <summary>
/// 保存域的视图状态
/// </summary>
private string dropdownlistVK = " FieldsList " ;
#endregion
#region IFilterProvider事件
/// <summary>
/// FilterProvider的事件
/// </summary>
public event SetFilterEventHandler SetFilter;
public event NoFilterEventHandler NoFilter;
public event ClearFilterEventHandler ClearFilter;
#endregion
#region 重写的接口方法
/// <summary>
/// 注册窗体
/// </summary>
public override void EnsureInterfaces()
{
try
{
// 功能类似于win32中的窗体注册
RegisterInterface( " myFilterProvider " ,
InterfaceTypes.IFilterProvider,
WebPart.LimitOneConnection,
ConnectionRunAt.Server,
this , "" , " 将过滤器提供给 " , " 过滤器 " , true );
}
catch (Exception ee)
{
errormsg = ee.ToString();
WriteLog(ee.ToString());
}
}
/// <summary>
/// 重写CanRunat方法
/// 在web part被重写之前通知asp.net基础结构
/// 检查欲重写的web part是否可以运行在当前配置之上
/// </summary>
/// <returns></returns>
public override ConnectionRunAt CanRunAt()
{
return ConnectionRunAt.Server;
}
/// <summary>
/// 获得Consumer一端的信息,
/// 通知此web part在预重写阶段
/// 已连接。
///
/// </summary>
/// <param name="interfaceName"> 指定的接口名称和RegisterInterface
/// 中的名称保持一致 </param>
/// <param name="connectedPart"> 连接上的web part </param>
/// <param name="connectedInterfaceName"></param>
/// <param name="runAt"></param>
public override void PartCommunicationConnect( string interfaceName,
Microsoft.SharePoint.WebPartPages.WebPart connectedPart,
string connectedInterfaceName,
ConnectionRunAt runAt)
{
try
{
if (interfaceName == " myFilterProvider " )
{
isConnected = true ;
consumername = connectedPart.Title;
}
}
catch (Exception ee)
{
lb_msg.Text = ee.ToString();
WriteLog(ee.ToString());
}
}
/// <summary>
/// 通信的主要展开点
/// 在这里可以触发
/// SetFilter
/// NoFilter
/// ClearFilter
/// 事件,可以按照需要来选择。
/// </summary>
public override void PartCommunicationMain()
{
int i = 0 ;
EnsureChildControls();
try
{
if (isConnected)
{
// 在这里设置过滤条件
// 过滤条件的格式为
// "FieldLabel"+{1
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
if (SetFilter != null && isSetFilterClicked)
{
// 匹配列
if (fieldList.Length == 0 )
lb_msg.Text = " 列数为0,不能筛选 " ;
else
for (; i < fieldList.Length; i ++ )
if (fielddspList[i] == ddl.SelectedItem.Text)
break ;
if (tb_input.Text != null )
filterExp = " FilterField1 " + " = " + fieldList[i] +
" & " +
" FilterValue1 " + " = " + tb_input.Text;
SetFilterEventArgs sea = new SetFilterEventArgs();
sea.FilterExpression = filterExp;
SetFilter( this , sea);
}
else if (ClearFilter != null && isClearFilterClicked)
{
ClearFilter( this , new EventArgs());
isClearFilterClicked = false ;
for (i = 0 ; i < fieldList.Length; i ++ )
fieldList[i] = fielddspList[i] = String.Empty;
}
else
if (NoFilter != null )
NoFilter( this , new EventArgs());
}
}
catch (Exception ee)
{
lb_msg.Text = ee.ToString() + " || 当前的i值 " + i;
WriteLog(ee.ToString());
}
}
/// <summary>
/// 这个事件由Consumer的PartCommunicationInit触发,
/// 作用是 接受由Consumer可能发出的一些参数列表,比如列表的栏名和显示名
/// </summary>
/// <param name="sender"></param>
/// <param name="filterConsumerInitEventArgs"></param>
public void FilterConsumerInit( object sender,
FilterConsumerInitEventArgs filterConsumerInitEventArgs)
{
if (filterConsumerInitEventArgs.FieldList != null )
fieldList = filterConsumerInitEventArgs.FieldList;
else
fieldList = null ;
if (filterConsumerInitEventArgs.FieldDisplayList != null )
fielddspList = filterConsumerInitEventArgs.FieldDisplayList;
else
fielddspList = null ;
if (ddl != null )
if (ddl.Items.Count == 0 && fieldList != null )
{
for ( int i = 0 ; i < fieldList.Length; i ++ )
ddl.Items.Add( new ListItem(fielddspList[i], fieldList[i]));
}
}
#endregion
protected override void RenderWebPart(HtmlTextWriter output)
{
if ( ! isConnected)
output.Write( " 请选择一个列表作为Consumer! " );
else
{
if (ddl.Items.Count == 0 && fieldList != null )
{
for ( int i = 0 ; i < fieldList.Length; i ++ )
ddl.Items.Add( new ListItem(fielddspList[i], fieldList[i]));
}
ddl.RenderControl(output);
tb_input.RenderControl(output);
btn_setfilter.RenderControl(output);
lb_msg.RenderControl(output);
btn_clearfilter.RenderControl(output);
}
}
protected override void CreateChildControls()
{
ddl = new DropDownList();
ddl.AutoPostBack = true ;
ddl.ID = " ddl " ;
btn_setfilter = new Button();
btn_clearfilter = new Button();
btn_clearfilter.Text = " 清除结果 " ;
lb_msg = new Label();
// if (ViewState[dropdownlistVK] == null && fieldList.Length != 0)
// {
// string dropdown = ViewState[dropdownlistVK];
// for (int i = 0; i < fieldList.Length; i++)
// {
// ddl.Items.Add(new ListItem(fielddspList[i], fieldList[i]));
// if (i < fieldList.Length - 1)
// ViewState[dropdownlistVK] += ddl.Items[i].Value;
// }
// }
btn_setfilter.Click += new EventHandler(btn_Click);
btn_clearfilter.Click += new EventHandler(btn_clearfilter_Click);
ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
tb_input = new TextBox();
// 设置文本框响应回车事件
tb_input.Attributes.Add( " onkeypress " , " <script language='javascript'>document.all. " + tb_input.ClientID + " .click;</script> " );
btn_setfilter.Text = " 提交 " ;
Controls.Add(ddl);
Controls.Add(tb_input);
Controls.Add(btn_setfilter);
Controls.Add(btn_clearfilter);
Controls.Add(lb_msg);
}
void btn_clearfilter_Click( object sender, EventArgs e)
{
isClearFilterClicked = true ;
}
void btn_Click( object sender, EventArgs e)
{
isSetFilterClicked = true ;
}
void ddl_SelectedIndexChanged( object sender, EventArgs e)
{
filtercondition = ddl.SelectedItem.Text;
}
private void WriteLog( string log)
{
string path = @" /log.txt " ;
if ( ! File.Exists(path))
using (StreamWriter sw = File.CreateText(path))
{
sw.Write(String.Format( " {0}: {1} " ,DateTime.Now,log));
}
using (StreamWriter sw = File.AppendText(path))
{
sw.Write(String.Format( " {0}: {1} " , DateTime.Now, log));
}
}
}
}
书写注意事项:
实现CreateChildControls如要重写RenderWebpart方法,需要在RenderWebpart中重新使用HtmlTextWriter输出,否则RenderWebpart会覆盖掉CreateChildControls方法输出的控件。
注意Provider连接Consumer的不同阶段,否则在创建控件输出的时候会出现问题。
因为有时候Web部件不会输出你的错误(这些错误往往是在创建用户控件的时候),最好可以写一个日志文件,便于查错。
必须要实现NoFilter事件,否则Web部件会报错,提示连接数过多,这和RegisterInterface函数中的连接数没有关系。
这里是使用效果截图:
过滤条件将会自动适应视图中的栏
![](https://i-blog.csdnimg.cn/blog_migrate/5ed4cae2d7507156c4e91659e3c22877.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/e110e7dcf0e1ea261e01f1071a5cb3e6.jpeg)
本文转自:http://www.cnblogs.com/burnett/archive/2007/03/22/684145.html