2013-04-02 110 views
2

我有一個自定義控件,裏面有一個DropDownList,它由CreateUserControl創建。我將數據源直接保存到下拉控件。頁面回發後,綁定的數據消失。我應該以一些棘手的方式自己保存/恢復綁定的數據嗎?自定義用戶控件數據源

public class EnumDropDownList : UserControl 
{ 
    private readonly DropDownList _ddlSelector; 
    private Dictionary<long, string> _dataSource; 

    public EnumDropDownList() 
    { 
     _ddlSelector = new DropDownList(); 
     _dataSource = new Dictionary<long, string>(); 
    } 


    public object DataSource 
    { 
     set 
     { 
      // datasource logic 
     } 
    } 

    public long SelectedValue 
    { 
     get { return Convert.ToInt64(_ddlSelector.SelectedValue); } 
     set { _ddlSelector.SelectedValue = value.ToString(); } 
    } 

    public override void DataBind() 
    { 
     _ddlSelector.DataSource = _dataSource; 
     _ddlSelector.DataTextField = "Value"; 
     _ddlSelector.DataValueField = "Key"; 
     _ddlSelector.DataBind(); 

     base.DataBind(); 
    } 

    [PermissionSet(SecurityAction.Demand, Name = "Execution")] 
    protected override void CreateChildControls() 
    { 
     Controls.Add(_ddlSelector); 
    } 
} 

回答

0

您的代碼是UserControlCustomServerControl組合。

如果你實現一個而不是組合,它可能會容易得多。

我創建了兩個控件 - UserControlCustomServerControl

用戶控件

放置下拉列表來代替ASPX裝載dymaiclally。如果您動態加載,則必須注意控制的持久性。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="EnumDropDownList.ascx.cs" 
    Inherits="WebApplication2010.EnumDropDownList" %> 
<asp:DropDownList runat="server" ID="DropDownList1" /> 

public partial class EnumDropDownList : System.Web.UI.UserControl 
{ 
    private Dictionary<long, string> _dataSource; 

    public EnumDropDownList() 
    { 
     _dataSource = new Dictionary<long, string>(); 
    } 

    public Dictionary<long, string> DataSource 
    { 
     set { _dataSource = value; } 
    } 

    public long SelectedValue 
    { 
     get { return Convert.ToInt64(DropDownList1.SelectedValue); } 
     set { DropDownList1.SelectedValue = value.ToString(); } 
    } 

    public override void DataBind() 
    { 
     DropDownList1.DataSource = _dataSource; 
     DropDownList1.DataTextField = "Value"; 
     DropDownList1.DataValueField = "Key"; 
     DropDownList1.DataBind(); 

     base.DataBind(); 
    } 
} 

自定義服務器控件(它是一個更容易實現對你的情況)

它基本上繼承的DropDownList Web控件。

public class MyDropDownList : DropDownList 
{ 
    public long SelectedInt64Value 
    { 
     get { return Convert.ToInt64(SelectedValue); } 
     set { SelectedValue = value.ToString(); } 
    } 

    public Dictionary<long, string> DataSource 
    { 
     get { return (Dictionary<long, string>)ViewState["DataSource"]; } 
     set { ViewState["DataSource"] = value; } 
    } 

    public override void DataBind() 
    { 
     foreach (var item in DataSource) 
      Items.Add(new ListItem(item.Value, item.Key.ToString())); 

     base.DataBind(); 
    } 
} 

使用

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm5.aspx.cs" Inherits="WebApplication2010.WebForm5" %> 

<%@ Register Src="EnumDropDownList.ascx" TagName="EnumDropDownList" TagPrefix="uc1" %> 
<%@ Register TagPrefix="asp" Namespace="WebApplication2010" Assembly="WebApplication2010" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <uc1:EnumDropDownList ID="EnumDropDownList1" runat="server" /> 
    <asp:Button runat="server" ID="Button1" Text="Submit" OnClick="Button1_Click" /> 
    <asp:MyDropDownList id="MyDropDownList1" runat="server" /> 
    </form> 
</body> 
</html> 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if(!IsPostBack) 
    { 
     Dictionary<long, string> dataSource = new Dictionary<long, string>(); 
     dataSource.Add(1, "One"); 
     dataSource.Add(2, "Two"); 

     EnumDropDownList1.DataSource = dataSource; 
     EnumDropDownList1.DataBind(); 

     MyDropDownList1.DataSource = dataSource; 
     MyDropDownList1.DataBind(); 
    } 
} 
0

在某些情況下,我已將數據集保存在會話變量中。 Whicn可以在回傳後引用。是這樣的:

Session.Add("dataSource", _dataSource);//create the session variable 

然後可以參考它,這取決於數據源是該類型(例如,在我使用了確定時代)

_ddlSelector.DataSource = (DataTable)Session["dataSource"]; 
+0

所以這是真的,我錯過了手動恢復數據源,但將這些數據保存到會話中並不是大項目中的好主意。 –

+0

那麼如果你需要它來保存,你可以緩存它(如會話示例),或者你可以再次調用數據庫來刷新然後重新綁定數據。 –

+0

但是我需要在適當的舞臺上做,比如覆蓋LoadControlState或LoadViewState ... –

0

這是aspx文件:

   <telerik:RadComboBox ID="cmbCurrency" runat="server" Width="200px" MaxHeight="200px" 
        EmptyMessage="Select a currency" AutoPostBack="true" Filter="Contains" EnableLoadOnDemand="true"> 
       </telerik:RadComboBox> 

這是後面的代碼:

if (!IsPostBack) 
      { 
       popCurrencyName();    
      }  

    public void popCurrencyName() 
       { 
        DataTable dtCurrency = objCurrencyBAL.getCurrency(long.MinValue); 

        if (dtCurrency.Rows.Count > 0) 
        { 
         cmbCurrency.DataSource = dtCurrency; 
         cmbCurrency.DataTextField = "Name"; 
         cmbCurrency.DataValueField = "CurrencyId"; 
         cmbCurrency.DataBind(); 
        } 
       } 

試試這個代碼: