自定义控件的构建(13)
讲过Eval之后,自然而然的就想到了Bind,我个人认为虽然ASP.NET中的绑定没有Silverlight中的绑定强大,但是都是属于基本功。
双向数据绑定
实现双向绑定主要用到IBindableTemplate返回的对象属性,这个接口也是从ITemplate接口继承的,其包含了2个方法
InstantiateIn()在具体控件中实例化模板的内容
ExtractValues()从模板中取得数据绑定表达式的值的集合
下面定义的TwowaysBinds控件代表一个包含Items产品的表单,
/// <summary>
/// 双向绑定
/// </summary>
public class TwowaysBinds : CompositeControl{public event EventHandler BindUpdate;private IBindableTemplate _editItemTemplet;
[TemplateContainer(typeof(Items),BindingDirection.TwoWay)]
[PersistenceMode(PersistenceMode.InnerProperty)]public IBindableTemplate EditItemTemplet
{get { return _editItemTemplet; }set { _editItemTemplet = value; }}private Items _item;
private IOrderedDictionary _result;
public IOrderedDictionary Result
{get
{return _result;
}}public string Name{get
{EnsureChildControls();return _item.Name;
}set
{EnsureChildControls();_item.Name = value;
}}public Decimal Price
{get
{EnsureChildControls();return _item.Price;
}set
{EnsureChildControls();_item.Price = value;
}}protected override void CreateChildControls(){_item = new Items();
_editItemTemplet.InstantiateIn(_item);this.Controls.Add(_item);
}protected override bool OnBubbleEvent(object source, EventArgs args){_result = _editItemTemplet.ExtractValues(_item);if (BindUpdate != null){BindUpdate(this,EventArgs.Empty);
}return true;}}
可以看到其包含了一个EditItemTemplet属性,表示一个双向数据绑定模板,对于这个属性我们重点关注一下:
首先它返回了IBindableTemplate的接口对象,其次,修饰该属性的TemplateContainer特性包含的参数BindingDirection,其值包括OneWay和TwoWay
那么对于上面代码的OnBubbleEvent(),其在子控件引发事件时调用。比如点击了EditItemTemplet中的Button时就会触发该事件。
其调用了ExtractValues(),返回一个Name/Value的OrderedDictionary
Items类和之前的一样:
public class Items : WebControl, IDataItemContainer{public string Name { get; set; }public decimal Price { get; set; }public object DataItem { get { return this; } }public int DataItemIndex { get { return 0; } }public int DisplayIndex { get { return 0; } }}
看看页面代码
<div><custom:TwowaysBinds ID="TwowaysBinds1" runat="server"onbindupdate="TwowaysBinds1_BindUpdate"><EditItemTemplet><asp:TextBox ID="TextBox1" Text="<%#Bind('Name') %>" runat="server"></asp:TextBox><br/><asp:TextBox ID="TextBox2" Text="<%#Bind('Price') %>" runat="server"></asp:TextBox><br /><asp:Button ID="Button1" runat="server" Text="Update" /></EditItemTemplet></custom:TwowaysBinds><hr /><asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br /><asp:Label ID="Label2" runat="server" Text="Label"></asp:Label></div>
cs.
protected void TwowaysBinds1_BindUpdate(object sender, EventArgs e){this.Label1.Text=this.TwowaysBinds1.Result["Name"].ToString();this.Label2.Text = this.TwowaysBinds1.Result["Price"].ToString();}
看看界面