【问题标题】:ASP.NET Triggering server-side events with multiple argumentsASP.NET 使用多个参数触发服务器端事件
【发布时间】:2009-08-06 14:51:00
【问题描述】:

恐怕我有一个相当冗长的问题。我对 ASP.NET 还很陌生,所以请多多包涵。 我已经为列出许多选项的 ASP.NET 页面构建了一个控件。每个选项都有两个可点击区域(为简单起见,称它们为按钮)。一个选择选项,一个隐藏选项。


protected void Page_Load(object sender, EventArgs e)
{
  RenderOptions();
}

public void RenderOptions()
{
  for (int i = 0; i < 5; i++) {
    HtmlGenericControl div1 = new HtmlGenericControl("div");
    div1.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(this, "option" + i));
    m_TreeContainer.Controls.Add(div1);

    HtmlGenericControl div2 = new HtmlGenericControl("div");
    div2.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(this, "option" + i));
    m_TreeContainer.Controls.Add(div2);
  }
}

public void RaisePostBackEvent(string arg) 
{
  //do something
}

这很好用(我确实实现了 IPostBackEventHandler 接口)。这里的问题是我似乎没有办法找到点击了哪个 HTML 元素,因此应该在 RaisePostBackEvent 方法中执行哪个操作。

我尝试创建一个新类 (HtmlDivControl),如下所示:


class HtmlDivControl : HtmlGenericControl, IPostBackEventHandler
{
  #region Delegates
  public delegate void ClickEventHandler(object sender, string eventArgument);
  #endregion

  #region Properties
  private ClickEventHandler m_Click;
  public ClickEventHandler Click
  {
    get { return m_Click; }
    set { m_Click = value; }
  }
  #endregion

  #region Constructors
  public HtmlDivControl()
  {
  }
  #endregion

  public void RaisePostBackEvent(string eventArgument)
  {
    m_Click.Invoke(this, eventArgument);
  }
}

现在我将 div1 和 div2 设为我的 HtmlDivControl 而不是 HtmlGenericControl,将 Click 属性设置为方法(委托)并将 div(div1 或 div2)本身作为 GetPostBackEventReference 方法的控件。这一次,我不仅可以区分 div,还可以预先确定应该执行的操作。但是,控件的 RaisePostBackEvent 是在 PageLoad 之后调用的。所以我现在遇到的问题是整个选项控件是在处理事件之前渲染的(因此,应该隐藏的选项不是因为实际隐藏发生在渲染之后)。将 RenderOptions() 调用移至 PageLoadComplete 方法也无济于事,因为那时 div 控件将不存在。

我很确定我在这里遗漏了一些非常基本的东西。但是有人可以解释一下我应该如何处理这样的事情吗?

附言 我应该如何在这里写下划线?他们习惯于使文本斜体?有转义字符吗?

【问题讨论】:

  • 你到底想用这个控件做什么?如果您是 ASP.Net 新手,我的建议是远离自定义控件类
  • Page_Load 是 Microsoft 提出的,而不是我 :-) 此外,这似乎不是破坏使用非常有效字符的一个很好的理由。但这是一个完全不同的讨论。 @John:如果我要远离自定义控件,那么我将如何学习 ASP.NET 更复杂的方面?澄清一下,我并不是在 ASP.NET 或一般编程方面迈出第一步,只是我现在进入了一个我并不完全熟悉的领域。根据我发布的内容,您可能会看到我将其引向了错误的方向。如果是这样,请指出正确的方法。
  • 我提到远离的原因是,除非您计划在其他项目中重新使用此控件,否则几乎总是有一个更简单/更优雅的内置控件解决方案,或者至少通过创建一个用户控件

标签: asp.net events onclick page-lifecycle


【解决方案1】:

对于刚接触 ASP.Net 的人来说,到目前为止,您已经做得很好了。您在这里的障碍实际上是您思考问题的方式。您应该很好地掌握 ASP.Net 页面生命周期 - 您缺少一些非常基本的东西。

简而言之,您希望页面将其状态重建为与回发之前相同的状态。然后处理你的事件。然后进行任何状态更改。

您正在考虑它,好像您的 html 控件应该在请求开始时知道它们的状态更改,这是不正确的。首先必须有重建阶段。这对于 ASP.Net 甚至确定要引发哪些事件至关重要。

我的建议:

  1. 将“RenderOptions()”方法移至 Page_Init 处理程序。如果您将 ViewState 合并到您的控件中,这将为您节省很多问题。 (我还要重命名它,因为它并没有真正呈现任何东西,它只是将您的控件添加到页面中。Render 在 ASP.Net 中具有特定的上下文)。

  2. 然后,在控件的 OnClick 事件处理程序中,只需根据需要设置控件的可见性,而不是尝试控制它们的呈现方式。将控件设置为 Visible=False 总是要简单得多,而不是尝试更改控件呈现到页面的方式。请记住,如果您设置 Visible=False,将向该控件的响应发送零个 html,但服务器仍会知道它在页面上,因此您仍然可以处理它。

将您的事件处理程序视为您将更改页面状态的地方。在这种情况下,您的逻辑应该在此处,而不是在 Page_Load 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    相关资源
    最近更新 更多