【问题标题】:Need Help with FindControl Function需要 FindControl 功能的帮助
【发布时间】:2009-05-22 21:44:38
【问题描述】:

我正在使用我一直在研究的转发器的表单,我目前正在尝试编写一个事件处理程序,它将在包含的表单之后获取转发器内某些控件的值转发器已提交。我假设如果我想从第一个转发器项目中检索标签,那么类似的东西会起作用,然后将它的文本设置为另一个标签的文本:

protected void SubmitMessage_Click(object sender, EventArgs e)
{
    Label MyLabel = (Label)MyRepeater.Items[0].FindControl("MessageID");
    MyLabel2.Text = MyLabel.Text;
}

然而,使用这个,MyLabel.Text 似乎是空的。在设置 MyLabel 后测试它是否为空时,结果为 false,因此我试图找出 MyLabel 在我尝试设置的中继器项目中没有相同内容的任何原因。 MyLabel2 已经在类的顶部声明。提前致谢。

编辑:.aspx 文件中的标签文本不是在文本属性内进行数据绑定,而是在标签本身的容器中。根据 Benjamin 的建议,我将在周二早上尝试另一种方法,只要我能回到我的代码中。

【问题讨论】:

  • Lush,您能否发布您的 HTML/ASPX 的 sn-p 以向我们展示您是如何生成它的。
  • 实际上,如果您可以发布 URL 或原始 HTML 输出,我可以说很多 - 我通常使用 FireBug 来查看信息是如何输出到屏幕上的。在那和快速观看之间,很容易找到任何东西
  • 输出的 HTML 只是一个空的 span。

标签: c# asp.net


【解决方案1】:

这取决于您如何将数据绑定到中继器上的标签。

<asp:Repeater ID="Repeater1" runat="server">

<ItemTemplate>

    <asp:Label ID="Label1" runat="server"><%# DataBinder.Eval(Container.DataItem,"CustomerName") %></asp:Label>

    <asp:Label ID="Label2" runat="server" Text=<%# DataBinder.Eval(Container.DataItem,"Country") %>></asp:Label>

    </ItemTemplate>
</asp:Repeater>

Label1 Text 属性未设置,数据 在客户端绑定到 Label 正文中的控件。 在 Label 设置后写入 span 标签呈现到页面并且从不直接绑定到标签控件。只有在标签正文中使用行内脚本时才会发生这种情况,如果只是文本,标签正文总是会覆盖标签的文本属性值。

对于 Label2,Text 属性被设置 所以绑定发生在服务器上强制它在完成渲染标签之前评估内联脚本,因此您的其他控件可以访问。

没有真正看到你的中继器,我怀疑这就是你的数据被绑定的方式。

这里有一些测试代码可以向你证明这种情况。

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataSet ds = new DataSet();
            DataTable dt = ds.Tables.Add("Customer");
            dt.Columns.Add("CustomerName", Type.GetType("System.String"));
            dt.Columns.Add("Country", Type.GetType("System.String"));

            DataRow dr = dt.NewRow();
            dr[0] = "Testcustomer1";
            dr[1] = "USA";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[0] = "Testcustomer2";
            dr[1] = "UK";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[0] = "Testcustomer3";
            dr[1] = "GERMANY";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr[0] = "Testcustomer4";
            dr[1] = "FRANCE";
            dt.Rows.Add(dr);

            //Bind the data to the Repeater
            Repeater1.DataSource = ds;
            Repeater1.DataMember = "Customer";
            Repeater1.DataBind();
        }

    }

    protected void SubmitMessage_Click(object sender, EventArgs e)
    {
        Label MyLabel = (Label)Repeater1.Items[0].FindControl("Label1");
        Label MyLabel2 = (Label)Repeater1.Items[0].FindControl("Label2");
        //Empty String Text was never set server side
        Label3.Text = MyLabel.Text;
        //String is found because Text was set
        Label4.Text = MyLabel2.Text;
    }

插入并添加几个额外的标签,您将看到 Label4 包含您要查找的数据,而 Label3 为空白。

【讨论】:

  • DataBinding 已经发生了,因为它在 Page_Load(或其他)之后和下一个 Page_load(或其他)之前...?
  • 数据在转发器中并显示在页面上,但如果没有明确设置标签文本属性并且他们将数据放在标签的正文中,那么标签本身永远不会真正绑定。标签不应该以这种方式设置,在这种情况下您可以看到原因。
  • 但是如何在标签内(而不是文本属性内)设置数据是在客户端而不是服务器端完成的;这是否意味着必须为浏览器生成 javascript 或类似的东西才能执行此操作?我没有做出断言,因为我面前没有任何代码,但据我所知,所有内联脚本都是在服务器端处理的。
  • 这可能是一个很好的问题,因为如果你做一些测试用例,你会得到完全不同的结果,这取决于你尝试做的事情的顺序。我不知道为什么它会以这种方式工作,我只知道它的作用以及如何形成它以获得您想要的结果,即使它们不是您在逻辑上期望的结果。如果您不在标签正文中使用内联脚本,则正文文本会覆盖 Text 属性文本,但内联脚本会将这些常规规则抛出窗口。
  • 我编辑了最初的答案以消除客户端渲染的混乱,而是使用了我认为会导致不一致的事件顺序。
【解决方案2】:

对此我不确定,但当事件执行时,中继器可能尚未重新填充。由于对该方法的调用是“ByVal”(VB 语言)而不是 ByRef,因此值可能会被传递,但尚未填充原始对象......只是一个想法......

【讨论】:

  • 深夜和几杯啤酒,所以不要太苛责我... ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-07
相关资源
最近更新 更多