我想要实现的目标是,如果用户控件已经添加到占位符,那么它将被删除,否则将被添加到它,它将在LinkButton的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);
}
}
答案 0 :(得分:2)
你可以不使用PlaceHolder并在那里一直控制。然后linkButton可以切换控件的可见性。
主要问题是您要将控件添加到页面linkButton单击。动态添加的控件在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
都需要。