在 WebControl.Render 方法之前和之后调用代码

发布于 2024-08-29 11:40:46 字数 1204 浏览 4 评论 0原文

我有一组自定义 ASP.NET 服务器控件,其中大部分派生自 CompositeControl。我想通过将每个控件包装在特定的 HTML/CSS 标记中,在所有控件类型中实现“必填”字段的统一外观。例如:

  <div class="requiredInputContainer">
        ...custom control markup...
  </div>

我很乐意以这样的方式抽象这种行为,以避免在现在和将来的每个自定义控件中都必须做一些丑陋的事情:

  public class MyServerControl : TextBox, IRequirableField { 

          public IRequirableField.IsRequired {get;set;}

          protected override void Render(HtmlTextWriter writer){

            RequiredFieldHelper.RenderBeginTag(this, writer)
            //render custom control markup
            RequiredFieldHelper.RenderEndTag(this, writer)
          }
   }

  public static class RequiredFieldHelper{

      public static void RenderBeginTag(IRequirableField field, HtmlTextWriter writer){
      //check field.IsRequired, render based on its values
      }
      public static void RenderEndTag(IRequirableField field, HtmlTextWriter writer){
       //check field.IsRequired , render based on its values
      }

  }

如果我正在派生所有自定义控件从同一个基类,我可以想象使用模板方法来强制执行之前/之后的行为;但是我有几个基类,而且我不想最终得到一个真正复杂的类层次结构。

感觉我应该能够通过利用 C# 的功能方面来设计更优雅的东西(即遵守 DRY 和 OCP),但我却一片空白。

I have a set of custom ASP.NET server controls, most of which derive from CompositeControl. I want to implement a uniform look for "required" fields across all control types by wrapping each control in a specific piece of HTML/CSS markup. For example:

  <div class="requiredInputContainer">
        ...custom control markup...
  </div>

I'd love to abstract this behavior in such a way as to avoid having to do something ugly like this in every custom control, present and future:

  public class MyServerControl : TextBox, IRequirableField { 

          public IRequirableField.IsRequired {get;set;}

          protected override void Render(HtmlTextWriter writer){

            RequiredFieldHelper.RenderBeginTag(this, writer)
            //render custom control markup
            RequiredFieldHelper.RenderEndTag(this, writer)
          }
   }

  public static class RequiredFieldHelper{

      public static void RenderBeginTag(IRequirableField field, HtmlTextWriter writer){
      //check field.IsRequired, render based on its values
      }
      public static void RenderEndTag(IRequirableField field, HtmlTextWriter writer){
       //check field.IsRequired , render based on its values
      }

  }

If I was deriving all of my custom controls from the same base class, I could conceivably use Template Method to enforce the before/after behavior;but I have several base classes and I'd rather not end up with really a convoluted class hierarchy anyway.

It feels like I should be able to design something more elegant (i.e. adheres to DRY and OCP) by leveraging the functional aspects of C#, but I'm drawing a blank.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

稍尽春風 2024-09-05 11:40:46

您有一个可选行为想要添加到某些对象而不是其他对象。这意味着您的问题中有一个 代理 模式。创建一个控件,该控件是其他控件的容器,并在渲染其任何子控件之前和之后执行所需的操作。

你不想继承专业化是对的。继承以创建抽象和变化。委派专攻。

编辑

/// <summary>
/// Create one of these panels for each required control
/// then place the required control into it
/// </summary>
public class ContainerForRequiredControls : Panel
{
  protected override void Render(HtmlTextWriter writer)
  {
    writer.Write("<!-- header -->");

    RenderChildren(writer);

    writer.Write("<!-- footer -->");
  }
}

You have an optional behavior you want to add to some objects and not others. That means you have a Proxy pattern in your problem. Create a control that is a container for other controls and does your required stuff before and after rendering any of its children.

You are right to not want to inherit to specialize. Inherit to create abstractions and variations. Delegate to specialize.

EDIT

/// <summary>
/// Create one of these panels for each required control
/// then place the required control into it
/// </summary>
public class ContainerForRequiredControls : Panel
{
  protected override void Render(HtmlTextWriter writer)
  {
    writer.Write("<!-- header -->");

    RenderChildren(writer);

    writer.Write("<!-- footer -->");
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文