自定义WebControl列在updateppanel 's asyncpostback触发器列表中,但当单击时

本文关键字:列表 单击 触发器 asyncpostback updateppanel 列在 WebControl 自定义 | 更新日期: 2023-09-27 18:14:55

我试图建立一个UserControl;一个视觉上可定制的链接按钮。一切都很好,直到UpdatePanels进入混合:我的fanybutton用户控件导致页面刷新。为了进行比较,我也使用了传统的LinkButton,它的工作效果很好。

//Doesn't work: Causes whole page to refresh/reload.
<as:FancyButton ID="fbUpload"
    runat="server" Text="FancyButton"/>
//Works as intended: Causes ajax refresh of Update Panel.
<asp:LinkButton ID="btnUpload" runat="server" Text="LinkButton" />

这是我的updatePanel代码:

<asp:UpdatePanel ID="upNewUpdatePanel" UpdateMode="Always" ChildrenAsTriggers="true"
    runat="server">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="fbUpload" EventName="Click" />
        <asp:AsyncPostBackTrigger ControlID="btnUpload" EventName="Click" />
    </Triggers>
    <ContentTemplate>
        <asp:PlaceHolder ID="detailPlaceHolder" runat="server" />
    </ContentTemplate>
</asp:UpdatePanel>

下面是fanybutton UserControl的代码:我很确定问题在这里:

using System;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace Jake
{
    public class FancyButton : WebControl, INamingContainer
    {
        private LinkButton _btn;

        public string Text
        {
            get
            {
                EnsureChildControls();
                return _btn.Text;
            }
            set
            {
                EnsureChildControls();
                _btn.Text = value;
            }
        }
        public string OnClientClick
        {
            get 
            {
                EnsureChildControls();
                return _btn.OnClientClick;
            }
            set
            {
                EnsureChildControls();
                _btn.OnClientClick = value;
            }
        }
        public delegate void ClickEventHandler(object sender, EventArgs e);
        public event ClickEventHandler Click = delegate { };
        protected void _btn_Click(object sender, EventArgs e)
        {
            Click(this, e);
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            EnsureChildControls();
        }
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            _btn = new LinkButton { ID = "btn" };
            Controls.Add(_btn);
        }
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
        }
        protected override void Render(HtmlTextWriter writer)
        {   
            //<a class="btn {Color} btn-{Color}{CssClass?}{hasImage?}">
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "fancyButton");
            _btn.RenderBeginTag(writer);
            if (Text != null)
            {
                writer.Write(Text);
            }
            _btn.RenderEndTag(writer);
        }
    }
}

TL;DR:正常的链接按钮作为异步触发器工作;我的自定义,UserControl按钮没有。我做错了什么?


接受答案的解

通过继承LinkButton而不是WebControl, Async面板更新按预期工作。此外,所有那些讨厌的override方法都变得不必要了。

namespace Jake
{
    public class FancyButton : LinkButton
    {
        public string Color
        {
            get
            {
                if ( ViewState["Color"] != null && ((string)ViewState["Color"]).Length > 0)
                {
                    return ((string)ViewState["Color"]).ToLower();
                }
                else return "white";
            }
            set { ViewState["Color"] = value; }
        }
        public string Icon
        {
            get { return (string)ViewState["Icon"]; }
            set { ViewState["Icon"] = value; }
        }
        protected override void Render(HtmlTextWriter writer)
        {
            //<a class="btn {Color} btn-{Color}{CssClass?}{hasImage?}">
            writer.AddAttribute(HtmlTextWriterAttribute.Class, string.Format("fancyButton {0}{1}{2}",
                this.Color,
                CssClass.Length > 0 ? " " + CssClass : string.Empty,
                Icon != null && Icon.Length > 0 ? " hasIcon" : String.Empty));
            this.RenderBeginTag(writer);
            // <span>
            writer.RenderBeginTag(HtmlTextWriterTag.Span);
            // <div class="icon {IconClass}"></div>
            if (Icon != null)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, string.Format("icon {0}{1}",
                    Icon,
                    Text != null ? " btnIconPadding" : ""));
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                writer.RenderEndTag();
            }
            if (Text != null)
            {
                writer.Write(Text);
            }
            // </span>
            writer.RenderEndTag();
            this.RenderEndTag(writer);
        }
    }
}

自定义WebControl列在updateppanel 's asyncpostback触发器列表中,但当单击时

不是100%确定,但我猜问题是,按钮引起回发是一个私人的一个从你的UserControl内部,你不能添加到你的触发器这么容易。

我能想到的最干净的解决方案是为您的可定制控件创建一个继承自LinkButton的类,而不是UserControl。缺点:没有视觉设计器或标记页。

在这个问题上快速搜索了一下,我间接地找到了Microsoft Connect:https://connect.microsoft.com/VisualStudio/feedback/details/524827/dynamicdataentities-site-linkbutton-in-updatepanel 详细信息

(不要费心阅读他从ASP链接的线程。. NET论坛(除非你喜欢撞墙)