2012-10-31 80 views
0

這裏是我的自定義控制代碼:爲什麼我的自定義模板數據綁定控件中的DataItem在ItemCommand事件中爲null?

namespace MyControlNameSpace 
{ 
    public class MyControlItemCommandEventArgs : CommandEventArgs 
    { 
    private MyControlItem _item; 
    private object _commandSource; 

    public MyControlItemCommandEventArgs(MyControlItem item, object commandSource, CommandEventArgs cea) : base(cea) 
    { 
     _item = item; 
     _commandSource = commandSource; 
    } 

    public MyControlItem Item { get{ return _item; } } 
    public object CommandSource { get{ return _commandSource; } } 

    } 

    public class MyControlItem : Control, IDataItemContainer 
    { 
    public MyControlItem(object dataItem, int index) 
    { 
     _dataItem = dataItem; 
     _dataItemIndex = _displayIndex = index; 
    } 

    private readonly object _dataItem; 
    private readonly int _dataItemIndex; 
    private readonly int _displayIndex; 

    public object DataItem { get { return _dataItem; } } 
    public int DataItemIndex { get { return _dataItemIndex; } } 
    public int DisplayIndex { get { return _displayIndex; } } 

    protected override bool OnBubbleEvent(object source, EventArgs args) 
    { 
     if (args is CommandEventArgs) 
     { 
     var e = new MyControlItemCommandEventArgs(this, source, (CommandEventArgs)args); 
     base.RaiseBubbleEvent(this, e); 
     return true; 
     } 

     return false; 
    } 
    } 

    public delegate void ItemEventHandler(object sender, MyControlItemCommandEventArgs e); 

    [DefaultProperty("Text")] 
    [ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")] 
    public class MyControl : CompositeDataBoundControl, IPrivilage 
    { 
    public event ItemEventHandler ItemCommand; 

    protected virtual void OnItemCommand(MyControlItemCommandEventArgs e) 
    { 
    if (ItemCommand != null) 
     ItemCommand(this, e); 
    } 

    protected override bool OnBubbleEvent(object source, EventArgs args) 
    { 
     // only bother bubbling appropriate events 
     if (args is MyControlItemCommandEventArgs) 
     { 
      OnItemCommand((MyControlItemCommandEventArgs)args); 
      return true; 
     } 

     return false; 
    } 

    protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding) 
    { 
     // here I'm adding some controls like buttons and other 

     // Iterate for ItemTemplate 
     foreach (object dataItem in dataSource) 
     { 
     if (ItemTemplate != null) 
     { 
      // create instance of MyControlItem control 
      var item = new MyControlItem(dataItem, count++); 
      // instantiate in new item object 
      ItemTemplate.InstantiateIn(item); 
      // add item to Controls collection 
      Controls.Add(item); 
      // need to support <%# %> expressions 
      item.DataBind(); 
     } 
     } 

     // some code here 
    } 
    } 

在.aspx頁面中:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // if it's not post back then get the data and assign to MyControl DataSource property 
    if(!IsPostBack) 
    GetData(); 
}  

protected void MyControl1_OnItemCommand(object sender, MyControlItemCommandEventArgs e) 
{ 
    var x = e.DataItem; 
    // x here is always null; 
} 

正如你可以看到我不能讓e.DataItem時OnItemCommand事件,因爲它總是空。
我試圖刪除Page_Load中的if(!IsPostBack),以便每次頁面加載數據源分配,但這是不正確的,我應該能夠不分配數據源,如果它是PostBack像在Asp.Net Repeater控制。

任何想法如何做到這一點?

回答

0

OnItemCommand事件是在事後引起的。此時,如果CompositeDataBoundControl已啓用ViewState,它將重新創建子控件而不查詢數據庫。將調用CreateChildControls方法,其中dataBinding設置爲false,而dataSource將爲可用作實際數據佔位符的可枚舉序列null

您將在任何數據綁定控件中獲得相同的行爲。如果您嘗試與Repeater同樣的事情,您會發現在ItemCommand事件中e.Item.DataItemnull

+0

因此,如果不重新分配數據源,沒有辦法做到這一點嗎? – Dabbas

+0

不是我見過的。 –

+0

我試圖使用和不使用'!IsPostBack'測試Repeater控件,DataItem在'OnItemCommand'事件中始終爲空。 – Dabbas

相關問題