从占位符添加和删除用户控件

时间:2012-04-14 12:42:42

标签: asp.net user-controls

我想要实现的目标是,如果用户控件已经添加到占位符,那么它将被删除,否则将被添加到它,它将在LinkBut​​ton的onclick中完成。

代码:

public partial class SiteSettings : System.Web.UI.Page {
    private UserSettings UserSettingsControl;
    protected void Page_Load(object sender, EventArgs e) {
        System.Diagnostics.Debug.WriteLine("Pageload");
        UserSettingsControl = LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
    }

    protected void UserLink_Click(object sender, EventArgs e) {     
        if (SettingsPlaceholder.Controls.Contains(UserSettingsControl)) {
        System.Diagnostics.Debug.WriteLine("Contains");
        SettingsPlaceholder.Controls.Remove(UserSettingsControl);
        } else {
        System.Diagnostics.Debug.WriteLine("Does not Contains");
        SettingsPlaceholder.Controls.Add(UserSettingsControl);
        }
    }
}

现在它无法正常工作。我得到了:

Pageload // on first time load
Pageload // on first time click
Does not Contains // on first time click
Pageload // on second time click
Does not Contains // on second time click

在“输出”窗口中。

我怎样才能做到这一点?我也尝试将它存储到ViewState中,但由于UserControl不可序列化,因此无效。

aspx页面是:

<telerik:RadAjaxManager ID="AjaxManager" runat="server">
    <AjaxSettings>
        <telerik:AjaxSetting AjaxControlID="UserLink">
            <UpdatedControls>
                <telerik:AjaxUpdatedControl ControlID="SettingsPanel" LoadingPanelID="LoadingPanel" UpdatePanelRenderMode="Block" />
                <telerik:AjaxUpdatedControl ControlID="PlaceHolderPanel" />
            </UpdatedControls>
        </telerik:AjaxSetting>            
    </AjaxSettings>
    <ClientEvents OnResponseEnd="respondEnd" />
</telerik:RadAjaxManager>
<asp:Panel ID="SettingsPanel" runat="server">
    <telerik:RadSplitter ID="MainSplitter" runat="server" MinHeight="200" Width="100%"
        OnClientLoaded="splitterLoaded" OnClientResized="splitterLoaded">
        <telerik:RadPane ID="LeftPane" runat="server" MaxWidth="250" Width="150" MinWidth="150" CssClass="left-rounded-corner settings-splitter-left">
            <asp:Panel runat="server">
                <asp:LinkButton ID="UserLink" runat="server" onclick="UserLink_Click" Text="User Settings" />                    
            </asp:Panel>
        </telerik:RadPane>
        <telerik:RadSplitBar ID="Splitbar" runat="server" CollapseMode="Forward" />
        <telerik:RadPane ID="RightPane" runat="server" CssClass="right-rounded-corner settings-splitter-right">
            <asp:Panel ID="PlaceHolderPanel" runat="server" Height="100%">
                <asp:PlaceHolder runat="server" ID="SettingsPlaceholder" />
            </asp:Panel>
        </telerik:RadPane>
    </telerik:RadSplitter>
</asp:Panel>
<telerik:RadAjaxLoadingPanel ID="LoadingPanel" runat="server" />

编辑:

修改后的代码:

public partial class SiteSettings : System.Web.UI.Page {

            protected void Page_Load(object sender, EventArgs e) {
                    if (!IsPostBack) {
                        AddUserSettings();
                    }
            }

            public UserControl UserSettingsControl {
                    get {
                            if (ViewState["UserSettings"] == null) {
                                    ViewState["UserSettings"] = LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
                            }
                            return (UserControl)ViewState["UserSettings"];
                    }
            }

        public UserControl SpaceSettingsControl {
                get {
                        if (ViewState["SpaceSettings"] == null) {
                                ViewState["SpaceSettings"] = LoadControl("~/UserControls/SpaceSettings.ascx") as SpaceSettings;
                        }
                        return (UserControl)ViewState["SpaceSettings"];
                }
        }

        protected void SettingsLink_OnCommand(object sender, CommandEventArgs commandEventArgs) {
                switch (commandEventArgs.CommandName) {
                    case "User":
                            AddUserSettings();
                            break;

                    case "Space":
                            AddSpaceSettings();
                            break;
                }
        }

        private void AddUserSettings() {
                AddSettings(UserSettingsControl);
        }

        private void AddSpaceSettings() {
                AddSettings(SpaceSettingsControl);
        }

        private void AddSettings(UserControl control) {
                SettingsPlaceholder.Controls.Add(control);
        }
}

2 个答案:

答案 0 :(得分:2)

你可以不使用PlaceHolder并在那里一直控制。然后linkBut​​ton可以切换控件的可见性。

主要问题是您要将控件添加到页面linkBut​​ton单击。动态添加的控件在Page_Init和Page_PreInit中添加时效果最佳,这允许它们维护其ViewState。此外,它们必须在每次回发时添加到占位符中。如果在您的示例中,在将SettingsControl添加到占位符后,另一个控件会导致回发,则SettingsControl将消失,因为它不会在每次回发时添加。

答案 1 :(得分:2)

Property中创建WebForm,如下所示。

public UserSettings UserSettingsControl 
{
    get
    {
        if (Session["MyControl"] == null)
            Session["MyControl"] = 
            LoadControl("~/UserControls/UserSettings.ascx") as UserSettings;
        return (UserSettings)Session["MyControl"];
    }
}

现在您可以访问UserSettingsControl的内存。因为它将持续Postback。在原始代码中,UserSettingsControl上的PostBack被重置为空。


  

Page Life Cycle结束时在运行时创建的所有控件   将被处置。最后,您找不到创建的控件   Postback之后的运行时。只有同一控件的重新创建才会   每个PostBack都需要。