用户控件的通用观察者模式

时间:2009-10-13 09:54:34

标签: design-patterns events user-controls observer-pattern

我想为用户控件实现通用的Observer模式。这样做的最佳方式是什么?

有3个用户控件:A,B& C。 这些用户控件中的每一个都是一组数据的表示。每个控件都有一个显示模式选择(基本或详细)。网站访问者可以选择哪种模式。在更改任何一个控件上的显示模式时,其他控件应反映该更改。

这里的杀手是用户控件可以由站点访问者动态地添加到页面中,因此页面可以具有任何控件的组合,包括它们中的任何一个。它们也可能出现在多个aspx页面上。

我在想Observer模式是最好的方法,是吗?如果有的话,最好的方法是什么呢?

谢谢, 理查德

2 个答案:

答案 0 :(得分:1)

  

在更改任何一个控件上的显示模式时,其他控件应反映该更改。

为什么页面上没有一个设置?为什么在所有控件中乘以相同的设置?

您可能有兴趣查看DropThings。它的作者还写了一本书,解释他是如何做到的。 Building a Web 2.0 Portal with ASP.NET 3.5

Building a Web 2.0 Portal with ASP.NET 3.5

答案 1 :(得分:1)

我处理了多个用户控件,需要响应同一条用户输入。

我创建了一个继承自System.Web.UI.Page的基页。我在这里将用户输入作为属性包含在内(稍后会详细介绍)。

我定义了这个界面

public interface IRespondToInput 
{
    int InputID 
    {
        get;
        set;
    }
}

好吧,它并没有被称为完全,而是我希望看到变更实现的每个用户控件。该接口由单个属性组成,它反映了基页中的属性。

public int InputID 
{
  get
  { 
    return _inputID 
  }
  set
  {
    _inputID = value;
    SetInputs(this, _inputID);
  }
}

在基页面方法的setter中,我调用一个例程,该例程以递归方式跳过控件层次结构,查找实现 IRespondToInput 的任何内容,并在找到匹配此接口的用户控件时设置该属性。 (见代码)

 protected void SetInputs( Control theControl, int theInputID )
    {
        if (theControl.Controls.Count > 0)
        {
            foreach (Control mySubControl in theControl.Controls)
            {
                if (mySubControl is UserControl || mySubControl is System.Web.UI.HtmlControls.HtmlForm)
                {
                    if (mySubControl is IRespondToInput)
                    {
                        ((IRespondToInput)mySubControl).InputID = theInputID;
                    }

                    SetInputs(mySubControl, theInputID);
                }
            }
        }
    }

这反过来会触发用户控件上的本地绑定事件。

事实上,我可以从继承的页面调用该属性。

e.g。 (在后面的用户控制代码中)

int mySetting = ((MyBasePage)Page).InputID;

我只是想将合规控件放到合规页面上并让它们工作。这种方法可能适合您。

为原创海报添加

如果您希望避免将此逻辑放在派生的基页中,为什么不创建一个单独的UserControl(D-继续您的示例)来封装您的切换逻辑,还会找到实现 IRespondToInput 界面?

在此UserControl中,您的setter将如下所示: -

public int InputID 
{
  get
  { 
    return _inputID 
  }
  set
  {
    _inputID = value;
    SetInputs(Page, _inputID);
  }
}

将此控件合并为UserControls A,B和C的子控件。

这样,您不必将每个页面 ADerivedPage - 只需将UserControl放到您需要的页面上即可。您可以将Page作为参数传递,因为它继承自Control