昨天做了两个使用自定义接口实现通信的WebParts,但是一直取不到数据,查看了一下网上的文章,好像都是要定义静态接口的,看看代码貌似要定义到被嵌套的aspx页面里,但是要修改aspx页面的话一定要使用sharepoint desiginer,没用过,比较麻烦...,也就没有验证了。然后用预定义接口IWebPartField来做,顺利取得了连接并传输了数据。
现在把做的代码做个copy,以后可以参考
(引用并修改了Scot Hillier的 《SharePoint Building Office 2007 Solutions in C# 2005》中的例子)
做出来后的效果如图
在TextProvider Web Part的文本框输入框里输入要发信的内容,按下Send Data键,页面刷新后FieldConsumerStub Web Part里会出现文本框的内容。
以下文字引用自清华大学出版社的《WebParts与自定义控件高级编程》,比较难懂.....可以当作一个参考。
提供程序指的是「TextProvider」,使用程序指的是「FieldConsumerStub」
IWebPartField接口包含一个方法和一个属性。
・该方法只有一个参数,允许提供程序调用使用程序中的某个历程(GetFieldValue)
・属性是只读的,返回描述该属性的一个对象(Schema)。
接口的这两个成员一起工作,来为使用程序提供数据和该数据的描述。下面概述其中的步骤
(1)提供数据的webpart调用使用程序中的连接点方法,给使用程序传送提供程序使用的接口引用。
(2)使用程序调用接口上的GetFieldValue方法,传送使用程序中某个历程的引用(这个历程必须是一个子例程,它接收一个Object类型的参数)。提供程序使用这个例程给使用程序传输数据。
(3)在提供程序中,执行GetFieldValue方法,并给它传送使用程序中已有的例程的引用。
(4)提供程序调用实用程序中的例程,并传送一个类型的Object参数。此时,提供程序在给使用程序提供数据。
(5)执行使用程序中的历程,接受提供程序传输过来的数据。
这个过程的灵活性要比上述描述的更大。例如,提供程序接收到使用程序中例程的引用,就可以随时调用该历程,只要不在GetFieldValue方法中即可。
下面是TextProvider的代码,注意须在提供者中实现[ConnectionProvider]方法
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace TextProvider
{
[Guid("25a611ed-ff66-44d8-8c8d-bdb2a4d1ecc5")]
public class TextProvider : System.Web.UI.WebControls.WebParts.WebPart, IWebPartField
{
//Member variables
protected Button button = null;
protected TextBox text = null;
string m_data = null;
//Text Property
[Personalizable(PersonalizationScope.Shared), WebBrowsable(false),
WebDisplayName("Text"),
WebDescription("The text to send")]
public string Text
{
get { return m_data; }
set { m_data = value; }
}
//Child controls
protected override void CreateChildControls()
{
button = new Button();
button.Text = "Send Data";
button.Click += new EventHandler(button_Click);
Controls.Add(button);
text = new TextBox();
Controls.Add(text);
}
//Show UI
protected override void RenderContents(HtmlTextWriter writer)
{
button.RenderControl(writer);
text.RenderControl(writer);
}
//The connection description
[ConnectionProvider("Text")]
public IWebPartField ConnectionInterface()
{
return this;
}
//Callback object
public void GetFieldValue(FieldCallback callback)
{
//Send data to consumer
callback.Invoke(text.Text);
}
//Publish schema
public PropertyDescriptor Schema
{
get
{ return TypeDescriptor.GetProperties(this)["Text"]; }
}
void button_Click(object sender, EventArgs e)
{
m_data = text.Text;
}
}
}
以及FieldConsumerStub的代码,注意代码中需要实现[ConnectionConsumer]方法
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Collections;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace FieldConsumerStub
{
[Guid("25a611ed-ff66-44d8-8c8d-bdb2a4d1ecc6")]
public class FieldConsumerStub : System.Web.UI.WebControls.WebParts.WebPart
{
IWebPartField ifld;
string str = string.Empty;
[ConnectionConsumer("Field")]
public void GetConnectionInterface(IWebPartField providerPart)
{
ifld = providerPart;
FieldCallback callback = new FieldCallback(ReceiveField);
providerPart.GetFieldValue(callback);
}
public void ReceiveField(object field)
{
PropertyDescriptor pd;
pd = ifld.Schema;
if (pd.PropertyType.Name == "String")
{
str=field.ToString();
}
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
writer.Write(str);
}
}
}
最后不要忘记把webparts的连接设成活动状态,不然代码对了东西也传不过去哦,如图