0

恐怕我有一个相当长的问题。我对 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 控件将不存在。

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

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

4

1 回答 1

2

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

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

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

我会推荐:

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

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

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

于 2009-08-06T15:47:02.330 回答