我有 2 个名为 UCCreateProfile.ascx(用于创建/编辑配置文件数据)和 UCProfileList.ascx(用于在 GridView 中显示配置文件数据)的用户控件。现在,每当创建新配置文件时,我都想更新我的 UCProfileList 控件以显示新条目。
针对上述问题的最佳解决方案是观察者模式。在我的例子中 UCCreatedProfile 是一个 Subject/Observable 并且 UCProfileList 是一个 Observer 并且根据观察者初始化时的模式定义,它知道谁是我的 Subject/Observable 并将自己添加到 Subject/Observable 列表中。因此,只要 Subject/Observable 发生更改,就会通知它。
这种模式最符合我的要求,但我在实现这个描述时遇到了一些问题,如下所示。
我在 CMS (Umbraco) 下工作,我没有任何物理容器页面 (.aspx)。我要做的是使用以下代码在 UCProfileList (Observer) onLoad 事件中找到 UCCreateProfile (Subject/Observable)。
private Control FindCreateProfileControl()
{
Control control = null;
Control frm = GetFormInstance();
control = GetControlRecursive(frm.Controls);
return control;
}
GetFormInstance() 方法在哪里
private Control GetFormInstance()
{
Control ctrl = this.Parent;
while (true)
{
ctrl = ctrl.Parent;
if (ctrl is HtmlForm)
{
break;
}
}
return ctrl;
}
和 GetControlRecursive() 方法是
private Control GetControlRecursive(ControlCollection ctrls)
{
Control result = null;
foreach (Control item in ctrls)
{
if (result != null) break;
if (item is UCCreateProfile)
{
result = item;
return result;
}
if (item.Controls != null)
result = GetControlRecursive(item.Controls);
}
return result;
}
这样我可以在 UCProfileList (Observer) 中找到 UCCreateProfile (Subject/Observable) 用户控件,但是找出 (Subject/Observable) 的方法不是那么快。如您所见,我需要遍历所有控件并首先找到 HtmlForm 控件,然后遍历 HtmlForm 控件下的所有子控件并找到我们正在寻找的适当控件。
其次,如果非常重要,将用户控件放置在容器中,我的代码只有在 UCProfileList.ascx(观察者)之前放置 UCCreatedProfile.ascx(主题/观察者)时才有效,因为这样 UCCreateProfile 将首先加载并在 UCProfileList 中查找。但是如果有人改变了这两个控件的位置,我的代码将无法工作。
因此,为了摆脱这些问题,我需要一些更快且独立于控件位置的解决方案。
我已经找到了一些解决方案,如下所述。请让我知道这是否是这样做的好方法。如果有替代方案,请告诉我。
我有一个会话级变量(带有 的字典Dictionary<ISubject, List<Observer>>
)。无论首先初始化/加载哪个用户控件,用户控件都会将自己添加到此字典中。
如果先添加了 Subject/Observable,则会在这个字典中找到对应的观察者。
如果 Observer 首先添加,它将添加到具有空条目的字典中。添加主题后,就建立了关联。
问候,
/里兹万