2012-11-16 32 views
0

我有一個網站形式(C#),坐在一個多視圖控件。 muliview控件有4個步驟,所以前3個步驟收集信息,如果有效則移動到按鈕單擊的下一個視圖。如何在按鈕單擊時以編程方式添加控件?

我想基於以前的答案動態構建表單,但從我讀過的內容到目前爲止,我還是有點不確定如何做到這一點。

例如,在步驟1中,用戶完成一些文本框控件並單擊提交。

根據面板1中提交的數據,下一個面板需要動態創建一些控件 - 一些標籤和一些文本框。

由於此點擊是在init和page_load之後,我不確定這將如何工作。

當然,我可以預先創建所有標籤/文本框控件,並根據需要禁用它們,但這似乎是相當差的資源使用。底線,我沒有經驗與動態控制工作,所以任何意見,將不勝感激。

+0

你在做什麼與第二面板的數據,有沒有任何按鈕,回發等?如果您在OnInit之後創建控件,它們仍然被創建,但回發數據不會自動設置。因此,如果您在第二個面板上調用回發,並且需要來自這些動態控件的數據,則需要從Request.Forms [dynamicControlClientId]獲取OnInit中的數據,或者將其存儲在ViewState中。另一個問題是你需要在回發後看到動態控件,所以你必須在第二個面板上存儲信息,以便如何在回發時創建控件(從第一個面板開始)。 – pawciu

+0

是的,會有更多的回傳。在所有的多視圖中有4個步驟,所以前3個會在回到下一步時回發。 – dotnetnoob

回答

1

好吧,下面我粘貼了工作示例。 事情需要注意的:

  • 爲了避免錯誤

Message=Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request. Source=System.Web ErrorCode=-2147467259

設定這個屬性上的動態控件

EnableViewState = false

數據在這個例子中是這樣

品牌引擎顏色成本
VW,1.2,黑色,72 000
VW,1.2,白色,70 000
VW,1.6 TDI,紅,79 500
VW,1.6 TDI,白色,78 800
福特1.6,黑色,57 600
福特,1.6,綠化,57 100
福特,2.0 TDCI,黑色,87 300
福特,2.0 TDCI,白色,86 600

Basicaly這就像這個:

  • 選擇汽車品牌和選擇按鈕(按鈕是我們的世代控制標準) 當然,你也可以做下降等邏輯。
  • 在第二屏幕上,您有一個或兩個下拉式選單,根據您選擇的
  • 如果你有兩個下拉菜單,二是取決於第一個下拉的選擇,讓你有依賴的例子,回傳

頁面代碼:

<form id="form1" runat="server"> 
<div> 
<asp:MultiView ID="mvPanels" runat="server"> 
    <asp:View ID="vPanel1" runat="server"> 
     <table> 
      <tbody> 
       <tr> 
        <td>Pick car</td> 
        <td><asp:DropDownList ID="ddlBrand" runat="server" /></td> 
        <td><asp:Button ID="btnPanel1Next" Text="Next" runat="server" 
          onclick="btnPanel1Next_Click" /></td> 
        <td><asp:Button ID="btnPanel1NextEngineOnly" Text="Next (pick engine only)" runat="server" 
          onclick="btnPanel1NextEngineOnly_Click" /></td> 
       </tr> 
      </tbody> 
     </table> 
    </asp:View> 
    <asp:View ID="vPanel2" runat="server"> 
     <%--<table> 
      <tbody> 
       <tr> 
        <td>Pick engine</td> 
        <td><asp:DropDownList ID="ddlEngine" AutoPostBack="true" runat="server" 
          onselectedindexchanged="ddlEngine_SelectedIndexChanged" /></td> 
        <td><asp:DropDownList ID="ddlColor" AutoPostBack="true" runat="server" 
          onselectedindexchanged="ddlColor_SelectedIndexChanged" /></td> 
        <td><asp:Button ID="btnPanel2Prev" Text="Prev" runat="server" 
          onclick="btnPanel2Prev_Click" /><asp:Button ID="btnPanel2Next" Text="Next" 
          runat="server" Enabled="False" onclick="btnPanel2Next_Click" /></td> 
       </tr> 
      </tbody> 
     </table>--%> 
    </asp:View> 
    <asp:View ID="vPanel3" runat="server"> 
     <table> 
      <tbody> 
       <tr> 
        <td><asp:Label ID="lblResult" runat="server" /></td> 
        <td><asp:Button ID="btnPanel3Prev" Text="Prev" runat="server" 
          onclick="btnPanel3Prev_Click" /><asp:Button ID="btnPanel3Finish" 
          Text="Confirm" runat="server" onclick="btnPanel3Finish_Click" /></td> 
       </tr> 
      </tbody> 
     </table> 
    </asp:View> 
</asp:MultiView> 
</div> 
</form> 

後面的代碼:

public partial class Default : System.Web.UI.Page 
{ 
    public class CarConfiguration 
    { 
     public string Brand { get; set; } 
     public string Engine { get; set; } 
     public PaintColor Paint { get; set; } 
     public string Cost { get; set; } 
    } 

    [Serializable] 
    public class CarConfigurationFilter 
    { 
     public string Brand { get; set; } 
     public string Engine { get; set; } 
     public PaintColor? Paint { get; set; } 
     public bool EngineOnly { get; set; } 
    } 

    public enum PaintColor 
    { 
     Black, 
     Red, 
     White, 
     Green, 
    } 

    public List<CarConfiguration> availableCars = new List<CarConfiguration> 
    { 
     new CarConfiguration{ 
      Brand = "VW", 
      Engine = "1.2", 
      Paint = PaintColor.Black, 
      Cost = "72 000", 
     }, 
     new CarConfiguration{ 
      Brand = "VW", 
      Engine = "1.2", 
      Paint = PaintColor.White, 
      Cost = "70 000", 
     }, 
     new CarConfiguration{ 
      Brand = "VW", 
      Engine = "1.6 TDI", 
      Paint = PaintColor.Red, 
      Cost = "79 500" 
     }, 
     new CarConfiguration{ 
      Brand = "VW", 
      Engine = "1.6 TDI", 
      Paint = PaintColor.White, 
      Cost = "78 800", 
     }, 
     new CarConfiguration{ 
      Brand = "Ford", 
      Engine = "1.6", 
      Paint = PaintColor.Black, 
      Cost = "57 600" 
     }, 
     new CarConfiguration{ 
      Brand = "Ford", 
      Engine = "1.6", 
      Paint = PaintColor.Green, 
      Cost = "57 100" 
     }, 
     new CarConfiguration{ 
      Brand = "Ford", 
      Engine = "2.0 TDCi", 
      Paint = PaintColor.Black, 
      Cost = "87 300" 
     }, 
     new CarConfiguration{ 
      Brand = "Ford", 
      Engine = "2.0 TDCi", 
      Paint = PaintColor.White, 
      Cost = "86 600" 
     }, 
    }; 

    CarConfigurationFilter filter 
    { 
     get { return (CarConfigurationFilter)ViewState["Filter"]; } 
     set { ViewState["Filter"] = value; } 
    } 

    //If you have multiview in control you need to create this in event before event PageLoad like LoadViewState, LoadControlState, LoadControlState 
    protected override void OnPreLoad(EventArgs e) 
    { 
     if (IsPostBack && mvPanels.ActiveViewIndex == 1) 
     { 
      CreateControlsOnPanel2(true, !filter.EngineOnly); 
     } 
     base.OnPreLoad(e); 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      ddlBrand.DataSource = availableCars.Select(x => x.Brand).Distinct(); 
      ddlBrand.DataBind(); 
      filter = new CarConfigurationFilter(); 
      mvPanels.ActiveViewIndex = 0; 
     } 
     base.OnLoad(e); 
    } 

    protected void btnPanel1Next_Click(object sender, EventArgs e) 
    { 
     filter.Brand = ddlBrand.SelectedValue; 
     filter.EngineOnly = false; 

     CreateControlsOnPanel2(true, true); 

     mvPanels.ActiveViewIndex++; 
    } 

    protected void btnPanel1NextEngineOnly_Click(object sender, EventArgs e) 
    { 
     filter.Brand = ddlBrand.SelectedValue; 
     filter.EngineOnly = true; 
     CreateControlsOnPanel2(true, false); 

     mvPanels.ActiveViewIndex++; 
    } 

    void CreateControlsOnPanel2(bool enginePickerEnabled, bool colorPickerEnabled) 
    { 
     var btnPanel2Prev = new Button(); 
     btnPanel2Prev.ID = "btnPanel1Prev"; 
     btnPanel2Prev.EnableViewState = false;  
     btnPanel2Prev.Text = "Prev"; 
     btnPanel2Prev.Click += btnPanel2Prev_Click; 

     var btnPanel2Next = new Button(); 
     btnPanel2Next.ID="btnPanel2Next"; 
     btnPanel2Next.Text = "Next"; 
     btnPanel2Next.EnableViewState = false; 
     btnPanel2Next.Enabled = false; 
     btnPanel2Next.Click += btnPanel2Next_Click; 


     if (enginePickerEnabled) 
     { 
      var ddlEngine = new DropDownList(); 
      ddlEngine.ID = "ddlEngine"; 
      ddlEngine.AutoPostBack = true; 
      ddlEngine.EnableViewState = false; 

      var engines = availableCars.Where(x => x.Brand == filter.Brand).Select(found => found.Engine).Distinct().ToList(); 
      engines.Insert(0, String.Empty); 
      ddlEngine.DataSource = engines; 
      ddlEngine.DataBind(); 
      if (!String.IsNullOrEmpty(filter.Engine)) 
      { 
       ddlEngine.SelectedValue = filter.Engine; 
       if (!colorPickerEnabled) 
        btnPanel2Next.Enabled = true; 
      } 
      else 
       ddlEngine.SelectedIndex = 0; 
      ddlEngine.SelectedIndexChanged += ddlEngine_SelectedIndexChanged; 
      vPanel2.Controls.Add(ddlEngine); 
     } 
     //remember to add ID to all dynamic controls or there might be an error on postback 
     if (colorPickerEnabled) 
     { 
      var ddlColor = new DropDownList(); 
      ddlColor.ID = "ddlColor"; 
      ddlColor.AutoPostBack = true; 
      ddlColor.EnableViewState = false; 
      ddlColor.SelectedIndexChanged += ddlColor_SelectedIndexChanged; 
      vPanel2.Controls.Add(ddlColor); 

      if (!String.IsNullOrEmpty(filter.Engine)) 
      { 
       var colors = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine).Select(found => found.Paint.ToString()).Distinct().ToList(); 
       colors.Insert(0, String.Empty); 
       ddlColor.DataSource = colors; 
       if (filter.Paint.HasValue) 
       { 
        ddlColor.SelectedValue = filter.Paint.Value.ToString(); 
        btnPanel2Next.Enabled = true; 
       } 

      } 
      else 
      { 
       ddlColor.DataSource = null; 
       ddlColor.SelectedIndex = 0; 
      } 
      ddlColor.DataBind(); 
     } 

     vPanel2.Controls.Add(btnPanel2Prev); 
     vPanel2.Controls.Add(btnPanel2Next); 
    } 

    protected void ddlEngine_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     var ddlEngine = sender as DropDownList; 
     var btnPanel2Next = (Button)vPanel2.FindControl("btnPanel2Next"); 

     if (!String.IsNullOrEmpty(ddlEngine.SelectedValue)) 
     { 
      filter.Engine = ddlEngine.SelectedValue; 
      var colors = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine).Select(found => found.Paint.ToString()).Distinct().ToList(); 
      colors.Insert(0, String.Empty); 
      filter.Paint = null; 

      var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor"); 
      if (ddlColor != null) 
      { 
       ddlColor.DataSource = colors; 
       ddlColor.DataBind(); 
       ddlColor.SelectedIndex = 0; 

       btnPanel2Next.Enabled = false; 
      } 
      else 
       btnPanel2Next.Enabled = true; 
     } 
     else 
     { 
      var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor"); 
      if (ddlColor != null) 
      { 
       ddlColor.Items.Clear(); 
       ddlColor.SelectedIndex = -1; 
      } 
      filter.Engine = null; 
      btnPanel2Next.Enabled = false; 
     } 
    } 

    protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor"); 
     var btnPanel2Next = (Button)vPanel2.FindControl("btnPanel2Next"); 

     if (!String.IsNullOrEmpty(ddlColor.SelectedValue)) 
     { 
      filter.Paint = (PaintColor)Enum.Parse(typeof(PaintColor), ddlColor.SelectedValue); 
      btnPanel2Next.Enabled = true; 
     } 
     else 
     { 
      filter.Paint = null; 
      btnPanel2Next.Enabled = false; 
     } 
    } 

    protected void btnPanel2Prev_Click(object sender, EventArgs e) 
    { 
     filter.Engine = null; 
     filter.Paint = null; 
     mvPanels.ActiveViewIndex--; 
    } 

    protected void btnPanel2Next_Click(object sender, EventArgs e) 
    { 
     mvPanels.ActiveViewIndex++; 

     var selectedConfiguration = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine 
     && (!filter.Paint.HasValue || x.Paint == filter.Paint)).Distinct().FirstOrDefault(); 
     if (selectedConfiguration != null) 
      lblResult.Text = String.Format("You have selected {0} {1} {2} for {3} PLN", selectedConfiguration.Brand, 
       selectedConfiguration.Engine, selectedConfiguration.Paint, selectedConfiguration.Cost); 
    } 

    protected void btnPanel3Prev_Click(object sender, EventArgs e) 
    { 
     mvPanels.ActiveViewIndex--; 
     CreateControlsOnPanel2(true, !filter.EngineOnly); 

    } 

    protected void btnPanel3Finish_Click(object sender, EventArgs e) 
    { 
    } 
} 

如果您有任何額外的問題,我會很樂意幫助

+0

感謝您的建議 – dotnetnoob

相關問題