1

我有 WebUserControl,它由 3 个 DropDownLists(日/月/年)组成。它具有公共属性 DateTime BirthDate。我在 Page (Page_Load) 上动态创建了这个 WebUserControl。我希望能够更改加载的 WebUserControl 中的数据并使用页面上的按钮保存它。

WebUserControl 代码:

public DateTime BirthDate { get; set; }

protected void Page_Load(object sender, EventArgs e)
{
    DropDownList dd = new DropDownList();
    DropDownList dm = new DropDownList();
    DropDownList dy = new DropDownList();

    this.Controls.Add(dd);
    this.Controls.Add(dm);
    this.Controls.Add(dy);

    dd.Items.Add(new ListItem("day","0"));
    dm.Items.Add(new ListItem("month", "0"));
    dy.Items.Add(new ListItem("year", "0"));

    dd.Items.AddRange(GetNumericValues(1, 31).ToArray());
    dm.Items.AddRange(GetNumericValues(1, 12).ToArray());
    int yearNow = DateTime.Now.Year;
    dy.Items.AddRange(GetNumericValues(yearNow - 100, yearNow - 17).ToArray());

    dd.DataBind();
    dm.DataBind();
    dy.DataBind();

    if (BirthDate != DateTime.MinValue)
    {
        dd.SelectedValue = BirthDate.Day.ToString();
        dm.SelectedValue = BirthDate.Month.ToString();
        dy.SelectedValue = BirthDate.Year.ToString();
    }
    else
    {                
        dd.SelectedValue = "0";
        dm.SelectedValue = "0";
        dy.SelectedValue = "0";
    }


}

private List<ListItem> GetNumericValues(int from, int to)
{
    List<ListItem> n = new List<ListItem>();
    for (int i = from; i <= to; i++)
    {
        n.Add(new ListItem(i < 10 ? "0" + i.ToString() : i.ToString()));
    }
    return n;
}

页面代码:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        BirthDateWebUserControl bc = new BirthDateWebUserControl();
        PanelForm.Controls.Add(bc);
        ViewState["BirthDateWebUserControl"] = bc;
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    BirthDateWebUserControl bc = (BirthDateWebUserControl)ViewState["BirthDateWebUserControl"];
    LabelResult.Text = bc.BirthDate.ToString("dd/MM/yy");
}

我做错了什么?

谢谢

4

4 回答 4

0

在每个页面回发时,必须在页面 PreInit 或 Init 事件中创建动态创建的控件。ASP.NET 将在 Init 和 Load 事件之间刷新控件的视图状态值。

于 2012-07-05T15:54:20.720 回答
0

假设您有UserControl以下内容:

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

目标是能够获取和设置 的值DropDownList,为此我们创建了一个UserControl能够这样做的属性。

public partial class Test : System.Web.UI.UserControl
{
    public string Value
    {
        get { return ddl1.SelectedValue; }
        set { ddl1.SelectedValue = value; }
    }
}

然后我们可以将它用作UserControl其他页面的属性。

<uc:Test ID="ucTest" runat="server" Value="1" />

或者

    protected void Page_Load(object sender, EventArgs e)
    {
        string theValue = ucTest.Value;
    }
于 2012-07-05T16:02:17.910 回答
0
if you want to pass data to user (FindControl because added dynamicly)

    you must use this

    public partial class UserControl1 : System.Web.UI.UserControl
    {
        public string Property
        {
            get { return dd.SelectedValue; }
            set { dd.SelectedValue = value; }
        }
    }


    When you create, affect UniqueId to your user control

    UserControl1 control = new UserControl1();
    control.UniqueId="Test";  
    add.....

    And find it in your page  with PreInit event before other events 

    UserControl1 control = (UserControl1)Page.FindControl("Test");
    control.Property = your value;



But if you want to pass data to your user control, this last must have this property with public modifier.
You can also pass with static forms as this example

<tagprefix:tagname id="" runat="server" Property="your value"/>
于 2012-07-05T16:11:33.840 回答
0

这是您的控件+页面的工作版本。

用户控制

using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;

public partial class BirthDateWebUserControl : System.Web.UI.UserControl
{
    private readonly string ViewStateKey = "BirthDateWebUserControl_VSKEY";
    public DateTime BirthDate
    {
        get
        {
            int day = int.Parse(((DropDownList)this.FindControl("DayDropDown")).SelectedValue);
            int month = int.Parse(((DropDownList)this.FindControl("MonthDropDown")).SelectedValue);
            int year = int.Parse(((DropDownList)this.FindControl("YearDropDown")).SelectedValue);
            return new DateTime(year, month, day);
        }
        set
        {
            ((DropDownList)this.FindControl("DayDropDown")).SelectedValue = value.Day.ToString("00");
            ((DropDownList)this.FindControl("MonthDropDown")).SelectedValue = value.Month.ToString("00");
            ((DropDownList)this.FindControl("YearDropDown")).SelectedValue = value.Year.ToString("00");
        }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        DropDownList dd = new DropDownList();
        dd.ID = "DayDropDown";
        DropDownList dm = new DropDownList();
        dm.ID = "MonthDropDown";
        DropDownList dy = new DropDownList();
        dy.ID = "YearDropDown";

        this.Controls.Add(dd);
        this.Controls.Add(dm);
        this.Controls.Add(dy);

        if (ViewState[ViewStateKey] == null)
        {

            dd.Items.Add(new ListItem("day", "0"));
            dm.Items.Add(new ListItem("month", "0"));
            dy.Items.Add(new ListItem("year", "0"));

            dd.Items.AddRange(GetNumericValues(1, 31).ToArray());
            dm.Items.AddRange(GetNumericValues(1, 12).ToArray());
            int yearNow = DateTime.Now.Year;
            dy.Items.AddRange(GetNumericValues(yearNow - 100, yearNow - 17).ToArray());

            dd.DataBind();
            dm.DataBind();
            dy.DataBind();

            ViewState[ViewStateKey] = true;
        }
    }

    private List<ListItem> GetNumericValues(int from, int to)
    {
        List<ListItem> n = new List<ListItem>();
        for (int i = from; i <= to; i++)
        {
            n.Add(new ListItem(i < 10 ? "0" + i.ToString() : i.ToString()));
        }
        return n;
    }
}

示例页面内容:

<asp:Panel ID="PanelForm" runat="server">
</asp:Panel>
<asp:Label ID="LabelResult" runat="server"></asp:Label>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Click" />

示例页面背后的代码:

protected void Page_Init(object sender, EventArgs e)
{
    BirthDateWebUserControl bc = new BirthDateWebUserControl();
    bc.ID = "bcInPanel";
    PanelForm.Controls.Add(bc);
}
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        // init with some date in case not post back
        ((BirthDateWebUserControl)PanelForm.FindControl("bcInPanel")).BirthDate = new DateTime(1950, 4, 12);
    }
}
protected void Button1_Click(object sender, EventArgs e)
{
    var bc = (BirthDateWebUserControl)PanelForm.FindControl("bcInPanel");
    LabelResult.Text = bc.BirthDate.ToString("dd/MM/yy");
} 

需要考虑的几点:

  • 使用动态控件时,初始化它们的合适位置是Page_Init
  • 在这种情况下(UserControl),初始化动态创建的子控件Page_Init
  • 将初始化控件所需的必要数据存储在ViewState. 不要存储整个控件本身。

最重要的是:

  • 质疑以 . 开头使用动态创建的控件是否有意义。在此示例中,用户控件中的下拉菜单也可以静态声明。它会使与他们一起工作更容易(不需要 FindControl + 强制转换来更正类型等)
于 2012-07-05T16:46:52.990 回答