自定义控件的构建(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();
    }

看看界面

捕获

posted @ 2010-08-11 17:36  ringgo  阅读(553)  评论(0编辑  收藏  举报