LinkBut​​ton和用户控制错误

时间:2010-02-06 20:08:11

标签: asp.net

我有一个用户控件,它由gridview和link按钮组成。问题是,链接按钮不起作用!有人可以看看,告诉我为什么以及如何解决它!

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var model = new List<UserControlProof.Model.Customer> {
            new UserControlProof.Model.Customer { 
                Name = "Customer1", address = "Addr1" }),
            new UserControlProof.Model.Customer { 
                Name = "Customer2", address = "Addr1" }),
            new UserControlProof.Model.Customer { 
                Name = "Customer3", address = "Addr2" }),
            new UserControlProof.Model.Customer { 
                Name = "Customer4", address = "Addr3" }) };

        var Addr = (from m in model select m.address).Distinct();
        foreach (string addr in Addr)
        {
            var cr = (UserControlProof.Controls.CollapseableRecordset)LoadControl(
                "Controls//CollapseableRecordset.ascx");
            cr.ID = cr.UniqueID;
            form1.Controls.Add(cr);
            cr.DisplayName = Addr;
            var filterredAddress = from m in model where m.address == addr select m;
            cr.DataSource = filterredAddress;
            cr.Count = filterredAddress.Count(); 

            if (cr.Count == 1) 
            {
                cr.ViewCustomers = true;
            }
            cr.DataBind();

            form1.Controls.Add(new Literal() { Text = "<br />" });
        }
    }
}

public partial class CollapseableRecordset : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GridView1.Columns.Clear();

            BoundField f1 = new BoundField();
            f1.DataField = "Customer";
            f1.ShowHeader = false;
            GridView1.Columns.Add(f1);
        }
    }

    //private string displayName;
    public string DisplayName
    {
        get
        {
            EnsureChildControls();
            return LabelName.Text;
            //return displayName;
        }
        set
        {
            EnsureChildControls();
            LabelName.Text = value;
            //displayName = value;
        }
    }

    //private int count;
    public int Count
    {
        get
        {
            EnsureChildControls();
            return int.Parse(LabelCount.Text);
            //return count;
        }
        set
        {
            EnsureChildControls();
            LabelCount.Text = value.ToString();
            //count = value;
        }
    }

    //private bool ViewCustomers;
    public bool ViewCustomers
    {
        get
        {
            EnsureChildControls();
            return Link1.Visible;
        }
        set
        {
            EnsureChildControls();
            Link1.Visible = value;
        }
    }

    public object DataSource
    {
        get
        {
            EnsureChildControls();
            return GridView1.DataSource;
        }
        set
        {
            EnsureChildControls();
            GridView1.DataSource = value;
        }
    }


    protected void Link1_Click(object sender, EventArgs e)
    {
        Label1.Visible = true;
    }
}

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CollapseableRecordset.ascx.cs" Inherits="UserControlProof.Controls.CollapseableRecordset" %>
<%@ Register Assembly="Microsoft.Practices.Web.UI.WebControls" Namespace="Microsoft.Practices.Web.UI.WebControls"
TagPrefix="pp" %>
<asp:Label ID="LabelName" runat="server" Text="Name"></asp:Label>
&nbsp;<asp:Label ID="LabelCount" runat="server" Text="Count"></asp:Label>
<asp:Panel ID="Panel1" runat="server">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
ShowHeader="False">
</asp:GridView>
<br />
<asp:Label ID="Label1" runat="server" Text="Label" Visible="false"></asp:Label>

</asp:Panel>
<asp:LinkButton ID="Link1" runat="server" Text="View All"></asp:LinkButton>

public class Customer
{
    public string Name { get; set; }
    public string address { get; set; }
}

5 个答案:

答案 0 :(得分:1)

您缺少在LinkButton中设置事件处理程序。你的按钮标记看起来应该更像这样:

<asp:LinkButton ID="Link1" runat="server" Text="View All" OnClick="Link1_Click"/>

对后续问题的回应

动态添加的事件处理程序不会“生存”ASP.NET页面生命周期。熟悉这个生命周期将有助于您理解Web表单编程。有关概述,请参阅this document

事件处理程序在未声明时停止工作的原因是ASP.NET生成的HTML页面不包含有关服务器端绑定的任何信息;这都是在回发期间设置的。 ASP.NET查看已发布的表单,检查发布数据中的项目,然后填充服务器端对象并根据页面定义调用事件处理程序。由于您的网页定义不包含LinkButton,因此无法知道如何调用您的事件处理程序。

简而言之,ASP.NET Web表单试图建立一个统一的,有状态的,客户端到服务器的形式的幻觉,但是当试图在通常模式之外做事时,这种错觉很容易被破坏。您可以解决这些限制,但如果您只是在标记中声明控件,那么您将使自己变得更容易。

以下是解决链接按钮问题的方法。在表单的Load事件中,查看Request.Form集合中的数据,看看lnkShowAllCust是否是回发的原因。如果是,请调用您的方法来处理点击。这基本上就是Web表单框架为您所做的:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        string eventSource = Request.Form["__EVENTTARGET"];
        if (eventSource != null && eventSource.EndsWith("lnkShowAllCust"))
        {
            Link1_Click(null, EventArgs.Empty);
        }
    }
}

答案 1 :(得分:0)

Click的{​​{1}}事件处理程序在哪里。

LinkButton

我假设的方法应该在点击Link1时执行,但我不知道你如何绑定事件。

答案 2 :(得分:0)

据我在CollapseableRecordset中所理解,您创建了一个boundfield并将其映射到Customer datafield

f1.DataField = "Customer";

但是您将客户列表绑定到您的控件(它是gridview),因此dataitem是“Customer”,但是如果您使用“Name”字段或

,则绑定的属性为“Name”和“address”
f1.DataField = "Name";

您将获得客户名单

答案 3 :(得分:0)

我已将click事件添加到控件中,是的,这是有效的。但是,在我的概念验证中,我动态添加了一个控件,并且这个控件不起作用,并且在标记中我添加了一个带有单击事件的链接按钮。

这是我的代码:

public partial class ucCustomerDetails : System.Web.UI.UserControl
{
    protected override void CreateChildControls( )
    {
        base.CreateChildControls( );

        this.lnkShowAllCust.ID = "lnkShowAllCust";
        this.lnkShowAllCust.Click += new EventHandler(this.lnkShowAllCust_Click);
        this.Controls.Add(lnkShowAllCust);
    }

    protected override void OnInit (EventArgs e)
    {
        CreateChildControls( );
        base.OnInit(e);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.EnsureChildControls( );
    }

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

    protected void lnkShowAllCust_Click(object sender, EventArgs e)
    {
        this.OnCustShowAllClicked(new EventArgs ( ));
    }

    protected virtual void OnCustShowAllClicked(EventArgs args)
    {
        if (this.ViewAllClicked != null)
        {
            this.ViewAllClicked(this, args);
        }
    }

    public event EventHandler ViewAllClicked;
} 

答案 4 :(得分:0)

如果您阅读了有关页面事件的链接,您将看到需要在Page_Load之前的事件中创建动态控件。 Page_Init几乎是推荐的事件。