Supporting Two-Way Databinding : CompositeControl « Custom Controls « ASP.NET Tutorial






Two-way databinding enables you to extract values from a template. 
You can use a two-way databinding expression not only to display the value of a data item, but also to update the value of a data item.

File: ProductForm.cs

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections.Specialized;

namespace myControls
{

    public class ProductForm : CompositeControl
    {
        public event EventHandler ProductUpdated;

        private IBindableTemplate _editItemTemplate;
        private ProductFormItem _item;
        private IOrderedDictionary _results;

        public IOrderedDictionary Results
        {
            get { return _results; }
        }

        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;
            }
        }

        [TemplateContainer(typeof(ProductFormItem), BindingDirection.TwoWay)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public IBindableTemplate EditItemTemplate
        {
            get { return _editItemTemplate; }
            set { _editItemTemplate = value; }
        }

        protected override void CreateChildControls()
        {
            _item = new ProductFormItem();
            _editItemTemplate.InstantiateIn(_item);
            Controls.Add(_item);
        }

        protected override bool OnBubbleEvent(object source, EventArgs args)
        {
            _results = _editItemTemplate.ExtractValues(_item);
            if (ProductUpdated != null)
                ProductUpdated(this, EventArgs.Empty);
            return true;
        }
    }

    public class ProductFormItem : WebControl, IDataItemContainer
    {
        private string _name;
        private decimal _price;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public decimal Price
        {
            get { return _price; }
            set { _price = value; }
        }

        public object DataItem
        {
            get { return this; }
        }

        public int DataItemIndex
        {
            get { return 0; }
        }

        public int DisplayIndex
        {
            get { return 0; }
        }

    }
}

File: Default.aspx

<%@ Page Language="C#" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    void Page_Load()
    {
        if (!Page.IsPostBack)
        {
            ProductForm1.Name = "Laptop";
            ProductForm1.Price = 433.12m;
            ProductForm1.DataBind();
        }
    }

    protected void ProductForm1_ProductUpdated(object sender, EventArgs e)
    {
        lblName.Text = ProductForm1.Results["Name"].ToString();
        lblPrice.Text = ProductForm1.Results["Price"].ToString();
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show ProductForm</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <custom:ProductForm
        id="ProductForm1"
        Runat="server" OnProductUpdated="ProductForm1_ProductUpdated">
        <EditItemTemplate>

        <asp:Label
            id="lblName"
            Text="Product Name:"
            AssociatedControlID="txtName"
            Runat="server" />
        <asp:TextBox
            id="txtName"
            Text='<%# Bind("Name") %>'
            Runat="server" />
        <br /><br />
        <asp:Label
            id="lblPrice"
            Text="Product Price:"
            AssociatedControlID="txtPrice"
            Runat="server" />
        <asp:TextBox
            id="txtPrice"
            Text='<%# Bind("Price") %>'
            Runat="server" />
        <br /><br />
        <asp:Button
            id="btnUpdate"
            Text="Update"
            Runat="server" />

        </EditItemTemplate>
    </custom:ProductForm>

    <hr />
    New Product Name:
    <asp:Label
        id="lblName"
        Runat="server" />

    <br /><br />

    New Product Price:
    <asp:Label
        id="lblPrice"
        Runat="server" />

    </div>
    </form>
</body>
</html>








14.20.CompositeControl
14.20.1.Building Composite Controls
14.20.2.Building Hybrid Controls
14.20.3.Performing layout with an HTML table.
14.20.4.Item Rotator
14.20.5.Image Rotator
14.20.6.Creating a Default Template
14.20.7.File: Product.cs
14.20.8.Supporting Two-Way Databinding
14.20.9.Creating Templated Databound Controls