asp.net 2.0 :web part 例子一:简单的通讯
例子一:简单的通讯
原文地址:
http://www.carlosag.net/Articles/WebParts/connectionsTutorial.aspx
目的:建立两个webpart,然后让这两个之间进行简单的通讯。
步骤:
1:新建website
2.0里面web项目不叫project了,叫website。
2:建立代码文件夹
右击website/新建文件夹/命名为“Code”。这是2.0里面的新特性,系统会在需要的时候到名字为“Code”的文件夹下找相关定义。
3:建立简单的通讯接口。右击“Code”文件夹/新建一个类文件/命名为“IMessage”。具体定义如下。
public interface IMessage
{
string Message { get;}
}
4:建立Provider WebPart
这是一个提供服务的webpart。我们通过向上加一个UserControl来制作简单的webpart。
注意:webpart框架只是运行这个webpart,如果放入其中的Control不是直接继承自webpart或者间接使用(比如UserControl之类的),那么webpart知识包装这个Control成“GenericWebPart”。
右击website新建一个UserConrol,命名为ProviderWebPart.ascx。这个控件继承自接口IMessage;有一个具有ConnectionProvider属性的方法GetMessage,该方法会把自己(this)返回;该控件还有一个按钮和文本框,用来改变Message。
代码如下:
<%@ Control Language="C#" ClassName="ProviderWebPart" %>
<%@ Implements Interface="IMessage" %>
<script runat="server">
[ConnectionProvider("Message")]
public IMessage GetMessage()
{
return this;
}
public string Message
{
get
{
return _messageTextBox.Text;
}
}
</script>
<asp:TextBox Runat="server" ID="_messageTextBox" />
<asp:Button Runat="server" ID="_postBackButton" Text="Change the Text" />
5:建立Consumer WebPart。
这个是用来使用消息的webpart。也是使用的一个UserControl。
右击website,新建名为ConsumerWebPart.ascx 的一个UserControl
这里面有一个具有ConnectionConsumer属性的方法,用来通讯。在他的OnPreRender事件里显示结果(因为这个这个事件触发的时候系统应该已经完成通讯了)
代码如下:
<%@ Control Language="C#" ClassName="ConsumerWebPart" %>
<script runat="server">
private IMessage _message;
[ConnectionConsumer("Message")]
void SetMessage(IMessage message)
{
this._message = message;
}
protected override void OnPreRender(EventArgs e)
{
if (_message != null)
_messageLabel.Text = _message.Message;
base.OnPreRender(e);
}
</script>
<asp:Label Runat="server" ID="_messageLabel" />
这个ConnectionConsumer属性就是一个receiver。
6:建立测试页面
创建一个aspx页面(我直接使用的default.aspx页面)
放置一个WebPartManager控件,编辑StaticConnections属性,添加一个connection,设置ID="SampleConnection" ConsumerID="ConsumerWebPart1" ProviderID="ProviderWebPart1" />。
然后放置一个WebPartZone 控件,向里面拖入刚才创建的两个UserControl(也就是webpart了)。
结果代码如下:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="uc1" TagName="ProviderWebPart" Src="ProviderWebPart.ascx" %>
<%@ Register TagPrefix="uc2" TagName="ConsumerWebPart" Src="ConsumerWebPart.ascx" %>
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="WebPartManager1" Runat="server">
<StaticConnections>
<asp:Connection ID="SampleConnection" ConsumerID="ConsumerWebPart1" ProviderID="ProviderWebPart1" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" Runat="server">
<ZoneTemplate>
<uc1:ProviderWebPart Runat="server" ID="ProviderWebPart1" />
<uc2:ConsumerWebPart Runat="server" ID="ConsumerWebPart1" />
</ZoneTemplate>
</asp:WebPartZone>
</form>
</body>
</html>
7:运行。
问题点数:0、回复次数:3Top
1 楼Dlwang2002(金银铜铁)回复于 2005-04-01 23:50:12 得分 0
例子二:直接继承自WebPart,还有好几个其他控件的简单应用
原文地址:http://www.carlosag.net/Articles/WebParts/moreRealSample.aspx
目的:一个wenpart的数据根据另一个参数获取。这些webpart不是直接添加上的,而是在程序运行中动态加上的。
步骤:
1:新建website
2:新建一个显示页面:
WebPartPageMenu :可以选择 修改webpart外观,连接webpart,添加webpart
WebPartZone :显示webpart的区域
ConnectionsZone :管理是否建立连接的区域。
DeclarativeCatalogPart :声明为存放区域。但是只是声明。可以在运行中动态添加webpart
页面代码如下:
<%@ Page Language="C#" %>
<%@ Register TagPrefix="my" Namespace="MyWebParts" %>
<html>
<head runat="server">
<title>WebParts Sample</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager runat="server" ID="WPM" />
<asp:WebPartPageMenu runat="server" ID="WPPM" />
<asp:WebPartZone runat="server" ID="Zone1" />
<asp:ConnectionsZone runat="server" ID="connectionsZone1" />
<asp:CatalogZone runat="server" ID="catalogZone1">
<ZoneTemplate>
<asp:DeclarativeCatalogPart runat="server" ID="declarative1">
<WebPartsTemplate>
<my:AuthorWebPart runat="server" ID="author1" Title="Authors" />
<my:BooksWebPart runat="server" ID="books1" Title="Books" />
</WebPartsTemplate>
</asp:DeclarativeCatalogPart>
<asp:PageCatalogPart runat="Server" ID="pageCatalog1" />
</ZoneTemplate>
</asp:CatalogZone>
</form>
</body>
</html>
3:创建Code文件夹,放一个代码文件名为“MyWebParts.cs”,源文件如下,不才添加了一写注释。
namespace MyWebParts
{
using System;
using System.Drawing;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
/// <summary>
/// WebPart to display the information of Authors
/// IField接口是webpart里面的用来标准的用来传递数据的接口
/// </summary>
public class AuthorWebPart : WebPart, IField
{
GridView _view;
public AuthorWebPart()
{
}
protected override void CreateChildControls()
{
_view = new GridView();//生成一个新的GridView,这是新的控件代替原来的DataGrid
_view.ID = "_authorsGrid";
_view.AutoGenerateColumns = true;
_view.DataKeyNames = new string[] { "au_id" };//设置主键
CommandField field = new CommandField();//生成一个命令按钮列
_view.SelectedRowStyle.BackColor = Color.Red;
field.ShowSelectButton = true;//显示select按钮
_view.Columns.Add(field);
SqlDataSource ds = new SqlDataSource();//连接SqlServer数据库
ds.ID = "_authorsDS";//设置主键
ds.ConnectionString = "server=carlosagmail;database=pubs;uid=sa;pwd=yourpassword";//连接字符串
ds.SelectCommand = "select au_id, au_lname, au_fname from authors";
_view.DataSourceID = ds.ID;
this.Controls.Add(ds);//添加一个ds
this.Controls.Add(_view);//把GridView控件加载上
}
[ConnectionProvider("AuthorID")]//提供连接的属性
public IField GetAuthor()//通讯接口,可以自己定义,如上一个例子
{
return this;//返回本身
}
#region IField Members 这里是接口的实现。%%%%%%
object IField.FieldValue
{
get
{
return _view.SelectedValue;//返回的是主键的值。因为上边已经定义为主键了
}
}
PropertyDescriptor IField.Schema
{
get
{
return TypeDescriptor.GetProperties(this.GetType())["FieldValue"];//???
}
}
#endregion
}
/// <summary>
/// WebPart to display the information of Books
/// 也是继承自WebPart。这个不是UserControl式的简单wrap了
/// </summary>
public class BooksWebPart : WebPart
{
private IField _authorField;
SqlDataSource _ds;
[ConnectionConsumer("Author")]//消息的“消费者”属性
public void SetAuthor(IField field)
{
this._authorField = field;
}
protected override void CreateChildControls()
{
GridView view = new GridView();
view.ID = "_booksGrid";
view.AutoGenerateColumns = true;
view.DataKeyNames = new string[] { "title_id" };//设置主键
CommandField field = new CommandField();//建立命令列
view.SelectedRowStyle.BackColor = Color.Red;
field.ShowSelectButton = true;//放置显示按钮
view.Columns.Add(field);//加入到view上。这些操作和DataGrid差别不大:)
_ds = new SqlDataSource();
_ds.ID = "_booksDS";
_ds.ConnectionString = "server=carlosagmail;database=pubs;uid=sa;pwd=yourpassword";//数据库连接字符串
view.DataSourceID = _ds.ID;//设置主键
this.Controls.Add(_ds);
this.Controls.Add(view);//添加到视图上
}
protected override void OnPreRender(EventArgs e)//在这里写,是为了让系统有时间处理消息的传递
{
const string selectStatement = "SELECT titles.title_id, titles.title, titles.type, titles.price, titles.pubdate FROM titles";
EnsureChildControls();//是否可以拥有自控件。
if (_authorField != null)//如果有消息传来,就按消息传来的参数获取数据。
{
if (_ds.SelectParameters.Count == 0)
{
_ds.SelectCommand = selectStatement + " INNER JOIN titleauthor ON titleauthor.title_id = titles.title_id WHERE (titleauthor.au_id = @au_id)";
_ds.SelectParameters.Add(new Parameter("au_id", TypeCode.String, (string)_authorField.FieldValue));
}
else
{
_ds.SelectParameters["au_id"].DefaultValue = (string)_authorField.FieldValue;
}
}
else//否则获取所有的数据。
{
_ds.SelectParameters.Clear();
_ds.SelectCommand = selectStatement;
}
_ds.DataBind();//绑定,显示
base.OnPreRender(e);
}
}
}
Top
2 楼Dlwang2002(金银铜铁)回复于 2005-04-01 23:50:49 得分 0
例子三:通过外部文件定义动态加载webpart到页面上。激动人心的功能。
目的:最终用户可以直接修改这个文件,然后就可以控制页面应该显示的webpart了。
着一个功能我们用来很长时间和才实现,现在他居然直接提供了这个功能!
步骤:
1:创建页面:
页面是空的,只有几个区域和一个WebPartPageMenu 用来调整
代码如下:
<%@ Page Language="C#" %>
<%@ Register Namespace="MyControls" TagPrefix="My" %>
<html>
<head />
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="WebPartManager1" runat="server" />
<asp:WebPartPageMenu ID="WebPartPageMenu1" runat="server" /><br />
<asp:WebPartZone ID="WebPartZone1" runat="server">
</asp:WebPartZone>
<br />
<asp:CatalogZone runat="server" ID="zone1">
<ZoneTemplate>
<My:XmlCatalogPart runat="server" id="xmlCatalogPart1"
datafile="~/parts.xml" title="Xml Catalog Part" />
</ZoneTemplate>
</asp:CatalogZone>
</form>
</body>
</html>
2:xml描述文件
这是用来描述界面上如何显示的文件。也可以使用DB来实现。
文件名为“parts.xml”
格式如下:
<?xml version="1.0" encoding="utf-8" ?>
<parts>
<part id="1" title="My Lottery WebPart" imageUrl="image1.gif" type="MyWebParts.LotteryPicker" />
<part id="2" title="My Weather WebPart" imageUrl="image2.gif" type="MyWebParts.WeatherWebPart" />
</parts>
最重要的是type属性,这里面存放的是webpart的type,系统可以通过这些信息从dll中读取webpart,加载。
3:CatalogPart的实现
这个类是用来读取xml文件,然后加载webpart的,文件名XmlCatalogPart.cs,放在Code文件夹里。
通过继承CatalogPart,我们获取激动人心的功能:自由的加载webpart!
代码如下:
namespace MyControls {
using System;
using System.Web.Caching;
using System.ComponentModel;
using System.Collections.Generic;
using System.Xml;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
/// <summary>
/// Catalog for reading WebParts from an Xml Document
/// </summary>
public class XmlCatalogPart : CatalogPart {
XmlDocument document;
/// <summary>
/// Overrides the Title to display Xml Catalog Part by default
/// </summary>
public override string Title {
get {
string title = base.Title;
return string.IsNullOrEmpty(title) ? "Xml Catalog Part" : title;
}
set {
base.Title = value;
}
}
/// <summary>
/// Specifies the Path for the Xml File that contains the declaration of the WebParts,
/// more specifically the WebPartDescriptions
/// </summary>
[
UrlProperty(),
DefaultValue(""),
Editor(typeof(System.Web.UI.Design.XmlUrlEditor), typeof(System.Drawing.Design.UITypeEditor)),
]
public string DataFile {
get {
object o = ViewState["DataFile"];
return o == null ? "" : (string)o;
}
set {
ViewState["DataFile"] = value;
}
}
/// <summary>
/// Creates a new instance of the class
/// </summary>
public XmlCatalogPart() {
}
/// <summary>
/// Returns the WebPartDescriptions
/// </summary>
public override WebPartDescriptionCollection GetAvailableWebPartDescriptions() {
if (this.DesignMode) {
return new WebPartDescriptionCollection(new object[] {
new WebPartDescription("1", "Xml WebPart 1", null),
new WebPartDescription("2", "Xml WebPart 2", null),
new WebPartDescription("3", "Xml WebPart 3", null)});
}
XmlDocument document = GetDocument();
List<WebPartDescription> list = new List<WebPartDescription>();
foreach (XmlElement element in document.SelectNodes("/parts/part")) {
list.Add(
new WebPartDescription(
element.GetAttribute("id"),
element.GetAttribute("title"),
element.GetAttribute("imageUrl")));
}
return new WebPartDescriptionCollection(list);
}
/// <summary>
/// Returns a new instance of the WebPart specified by the description
/// </summary>
public override WebPart GetWebPart(WebPartDescription description) {
string typeName = this.GetTypeNameFromXml(description.ID);
Type type = Type.GetType(typeName);
return Activator.CreateInstance(type, null) as WebPart;
}
/// <summary>
/// private function to load the document and cache it
/// </summary>
private XmlDocument GetDocument() {
string file = Context.Server.MapPath(this.DataFile);
string key = "__xmlCatalog:" + file.ToLower();
XmlDocument document = Context.Cache[key] as XmlDocument;
if (document == null) {
using (CacheDependency dependency = new CacheDependency(file)) {
document = new XmlDocument();
document.Load(file);
Context.Cache.Add(key, document, dependency,
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
return document;
}
/// <summary>
/// Returns the type
/// </summary>
private string GetTypeNameFromXml(string webPartID) {
XmlDocument document = GetDocument();
XmlElement element = (XmlElement)document.SelectSingleNode("/parts/part[@id='" + webPartID + "']");
return element.GetAttribute("type");
}
}
}
Top
3 楼goon2005(继续)回复于 2005-04-03 16:02:23 得分 0
呵呵,研究一下Top




