我已经处理了多个需要响应同一用户输入的用户控件。
我创建了一个继承自 System.Web.UI.Page 的基本页面。我在这里将用户输入作为属性包含在内(稍后会详细介绍)。
我定义了这个接口
public interface IRespondToInput
{
int InputID
{
get;
set;
}
}
好的,它的名称并不准确,但是我希望看到更改已实现的每个用户控件。该接口由一个属性组成,它反映了基本页面中的属性。
public int InputID
{
get
{
return _inputID
}
set
{
_inputID = value;
SetInputs(this, _inputID);
}
}
在基页方法的设置器中,我调用了一个例程,该例程递归地跳过控件层次结构,查找实现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);
}
}
}
}
这反过来又会触发用户控件上的本地绑定事件。
事实上,我本可以从继承的页面中调用该属性。
例如(在用户控制代码后面)
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 的子控件。
这样,您不必将每个页面都设置为ADrivedPage - 您只需将 UserControls 放到您需要它们的页面上即可。而且你会很好地Page
作为参数传递,因为它继承自Control
.