如何显式维护动态创建的用户控件的视图状态?

发布于 2024-12-05 09:54:56 字数 2060 浏览 11 评论 0原文

我有一个搜索表单,提供了许多不同的搜索选项,例如“搜索自然名称”、“搜索法定名称”、“搜索地址”等。这些是由 PropertySearchOption 类。每个搜索选项指定一个包含该选项所需的搜索字段的用户控件,例如,自然姓名选项具有姓名字段。使用的搜索选项由主搜索页面上的RadioButtonList 确定,当此列表中的选择发生变化时,我会动态加载所需的用户控件。我的问题是我找不到一种方法来保留动态控件及其搜索字段的视图状态。这是我正在使用的核心代码:

<asp:RadioButtonList ID="searchTypeOptions" runat="server" AutoPostBack="true" RepeatDirection="Horizontal" RepeatLayout="Flow" OnSelectedIndexChanged="SearchTypeOptionsSelectedIndexChanged">
    <asp:ListItem Value="NaturalName">Name (Natural)</asp:ListItem>
    <asp:ListItem Value="LegalName">Legal Name (Business)</asp:ListItem>
    <asp:ListItem Value="ErfDetails">Erf Details</asp:ListItem>
    <asp:ListItem Value="PhysicalAddress">Physical Address</asp:ListItem>
    <asp:ListItem Value="FarmDetails">Farm</asp:ListItem>
</asp:RadioButtonList>

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var typeOption = searchTypeOptions.SelectedItem;
        if (typeOption == null)
        {
            searchTypeOptions.SelectedValue = "ErfDetails";
            LoadSearchForm();
        }
    }
}

protected void SearchTypeOptionsSelectedIndexChanged(object sender, EventArgs e)
{
    LoadSearchForm();
}

protected virtual void LoadSearchForm()
{
    SearchOption = (PropertySearchOption)typeof(PropertySearchOption).GetProperty(searchTypeOptions.SelectedValue, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
    searchFormPlaceHolder.Controls.Clear();
    var searchForm = LoadControl(SearchOption.FormControlUrl);
    searchFormPlaceHolder.Controls.Add(searchForm);
    searchTypeLabel.Text = SearchOption.Description;
}

我必须在 searchFormPlaceHolder 上将 EnableViewState 设置为 false,否则当我尝试更改当前选项时会出现视图状态异常,例如搜索表单的动态选择效果很好。但是,在按钮上单击回发执行搜索时,我丢失了搜索表单,因为它仅在第一次加载时在 Page_Init 中创建,而不是回发。如果我将 LoadSearchForm 放在 if 块之外,则会失败,因为在回发时,单选按钮列表的 SelectedValue 为空。

遇到这样的情况,我除了逃跑还能做什么?

I have a search form that offers a number of different search options, such as 'search on natural name', 'search on legal name', 'search on address' etc. These are defined by static 'factory' methods on a PropertySearchOption class. Each search option specifies a user control containing the search fields required for that optiom, e.g. the natural name option has name and surname fields. The search option used is determined by a RadioButtonList on the main search page, and when the selection changes in this list I dynamically load the required user control. My problem is that I can't find a way to preserve the view state of the dynamical control and its search fields. Here is the core code I am using:

<asp:RadioButtonList ID="searchTypeOptions" runat="server" AutoPostBack="true" RepeatDirection="Horizontal" RepeatLayout="Flow" OnSelectedIndexChanged="SearchTypeOptionsSelectedIndexChanged">
    <asp:ListItem Value="NaturalName">Name (Natural)</asp:ListItem>
    <asp:ListItem Value="LegalName">Legal Name (Business)</asp:ListItem>
    <asp:ListItem Value="ErfDetails">Erf Details</asp:ListItem>
    <asp:ListItem Value="PhysicalAddress">Physical Address</asp:ListItem>
    <asp:ListItem Value="FarmDetails">Farm</asp:ListItem>
</asp:RadioButtonList>

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var typeOption = searchTypeOptions.SelectedItem;
        if (typeOption == null)
        {
            searchTypeOptions.SelectedValue = "ErfDetails";
            LoadSearchForm();
        }
    }
}

protected void SearchTypeOptionsSelectedIndexChanged(object sender, EventArgs e)
{
    LoadSearchForm();
}

protected virtual void LoadSearchForm()
{
    SearchOption = (PropertySearchOption)typeof(PropertySearchOption).GetProperty(searchTypeOptions.SelectedValue, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
    searchFormPlaceHolder.Controls.Clear();
    var searchForm = LoadControl(SearchOption.FormControlUrl);
    searchFormPlaceHolder.Controls.Add(searchForm);
    searchTypeLabel.Text = SearchOption.Description;
}

I have to set EnableViewState to false on searchFormPlaceHolder, or I get a viewstate exception when I try and change the current option, and like this the dynamic selection of search forms works fine. However, on the button click postback to perform the search, I lose the search form, because it is only created in Page_Init on the first load, not postbacks. If I place LoadSearchForm outside the if block, it fails because on postback, the SelectedValue of the radio button list is empty.

What can I do, or what should I do, to in a scenario like this, besides run away?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

败给现实 2024-12-12 09:54:56

您可以将搜索类型选项保存在 HiddenField 中,以便您可以在每次回发时创建搜索表单(并记住为动态创建的控件设置唯一的 id)

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var typeOption = searchTypeOptions.SelectedItem;
        if (typeOption == null)
        {
            searchTypeOptions.SelectedValue =
                 myHiddenField.Value = "ErfDetails";
            LoadSearchForm("ErfDetails");
        }
    }
    else
       LoadSearchForm(Request.Form[myHiddenField.UniqueID]);
}

override void OnPreRender(EventArgs e) {
    myHiddenField.Value = searchTypeOptions.SelectedValue;
}

protected void SearchTypeOptionsSelectedIndexChanged(object sender, EventArgs e)
{
    LoadSearchForm(searchTypeOptions.SelectedValue);
}

protected virtual void LoadSearchForm(string option)
{
    SearchOption = (PropertySearchOption)typeof(PropertySearchOption).GetProperty(option, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
    searchFormPlaceHolder.Controls.Clear();
    var searchForm = LoadControl(SearchOption.FormControlUrl);

    searchForm.ID = "mySearchForm";

    searchFormPlaceHolder.Controls.Add(searchForm);
    searchTypeLabel.Text = SearchOption.Description;
}

You can save the search type option in a HiddenField, so you can create the search form at each postback (and remember to set a unique id to your dynamically created controls)

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        var typeOption = searchTypeOptions.SelectedItem;
        if (typeOption == null)
        {
            searchTypeOptions.SelectedValue =
                 myHiddenField.Value = "ErfDetails";
            LoadSearchForm("ErfDetails");
        }
    }
    else
       LoadSearchForm(Request.Form[myHiddenField.UniqueID]);
}

override void OnPreRender(EventArgs e) {
    myHiddenField.Value = searchTypeOptions.SelectedValue;
}

protected void SearchTypeOptionsSelectedIndexChanged(object sender, EventArgs e)
{
    LoadSearchForm(searchTypeOptions.SelectedValue);
}

protected virtual void LoadSearchForm(string option)
{
    SearchOption = (PropertySearchOption)typeof(PropertySearchOption).GetProperty(option, BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
    searchFormPlaceHolder.Controls.Clear();
    var searchForm = LoadControl(SearchOption.FormControlUrl);

    searchForm.ID = "mySearchForm";

    searchFormPlaceHolder.Controls.Add(searchForm);
    searchTypeLabel.Text = SearchOption.Description;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文