65.9K
CodeProject 正在变化。 阅读更多。
Home

告别 MultiView!

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.83/5 (5投票s)

2007年5月5日

CPOL

4分钟阅读

viewsIcon

34252

downloadIcon

252

一种更具动态性、灵活性和直观性的视图处理方法。忘掉 MultiView 吧!

引言

在本文中,我将展示一个我创建的名为 ViewManager 的类。它基本上允许您将任何控件添加到其内部的视图及其关联控件的列表中。它最适用于利用多个视图的 Web 窗体(例如,为每个不同的用户角色提供不同外观的窗体,或如示例所示,管理更复杂的视图/编辑视图)。这个工具与其他工具的一个关键区别在于,它允许您将同一个控件放入多个视图中。它还允许您在代码的一个中心位置轻松快速地维护您的视图。

背景

在我工作的地方,我经常遇到需要同时管理许多对象可见性的代码。本质上,Web 窗体试图营造一种它们是两个或三个不同页面的错觉,但实际上它们只是一个页面。我个人宁愿看到这些页面是独立的页面,但我需要一个中间步骤来进行重构(代码隐藏文件很容易超过一千行代码,所以我喜欢采取小步骤,以便我的测试可以更彻底)。

那么我能做什么呢?我可以使用面板或视图控件。在视图管理方面,视图控件比面板略占优势,但如果某些控件属于多个视图怎么办?如果构成我视图的控件是交错的怎么办?这时就轮到我的工具 ViewManager 类了。

Using the Code

好的,您有了这个类,但如何使用它呢?您经常看到其他程序员提供的类,它们功能强大,但需要您考虑的事情太多,以至于几乎无用。我将尽力将其分解得尽可能简单。

在示例项目中,我这样切换到编辑模式和只读模式

protected void EditButton_Click(object sender, EventArgs e)
{
    MyViewManager.SetActiveView(EditCustomerViewName);
}

protected void SaveButton_Click(object sender, EventArgs e)
{
    MyViewManager.SetActiveView(ViewCustomerViewName);
}

EditCustomerViewNameViewCustomerViewName 是保存各自视图名称的字符串变量。我将它们设置为我的 Page 类中全局可访问的变量,以便不同的方法可以访问相同的名称而无需复制字符串。

最复杂的部分是将每个视图与其子控件关联。我就是这样做的。我将首先向您展示我关联编辑控件的方式。

protected void InitializeViews()
{
    MyViewManager = new ViewManager();

    List<Control> EditableCustNames = new List<Control>();
    EditableCustNames.Add(FirstNameField);
    EditableCustNames.Add(MiddleInitialField);
    EditableCustNames.Add(LastNameField);

    MyViewManager.Add(EditCustomerViewName, SaveButton);
    //Notice that here we can also populate the view using a 
    //ready made list.
    MyViewManager.Add(EditCustomerViewName,EditableCustNames);

我创建了一个名为 InitializeViews 的方法。这为我提供了一个中心位置,我可以在其中设置我的 ViewManager(它也对 Page 类全局可访问)。接下来我做的是创建一个控件列表。我这样做只是为了逻辑上将控件分组。在此示例中,该列表中的每个控件都是用于编辑客户名称的控件。您不必通过列表添加控件。还有一个重载,用于处理以分段方式将控件分配给每个视图,正如我们在示例的最后一行中看到的。

再次强调,EditCustomerViewName 只是一个字符串。我也可以轻松地将变量替换为实际的字符串 "Edit Customer"。我选择使用变量是因为拼写至关重要。视图不是强类型的,因此直到运行时才会发现任何错误。所以,我再次强调,在代码的一个位置(或使用结构体)输入您的视图名称,并通过变量名引用,这样它就是强类型的。

基本上就是这样。如果您愿意,也可以删除视图。在此示例中我没有这样做,但调用 MyViewManager.RemoveView(EditCustomerViewName) 即可。

关注点

该类本身利用了一个 Dictionary 对象,该对象包含与强类型 ListList<Control>)关联的键。幸运的是,C# 会在控件之间一直向下到列表维护引用,因此对列表中某个控件的更改与对控件本身的更改效果相同。

还有一点...

添加到视图后,控件的 Visible 属性会设置为 false。基本上,如果您没有明确设置某个视图为活动状态,则假定该视图为非活动状态。另一个注意事项是,一次只能有一个视图处于活动状态。考虑到可以将控件重叠到多个视图中的能力,这不应成为限制因素,但此处提及是为了让您了解该类的假设。

还有另一件事...

由于一个非常简短的文章中的一个评论,我写了这篇更详尽的文章。最初的文章仅面向中高级开发人员,因为我使用了单元测试来记录代码,并期望开发人员能够利用这一点。我希望这能帮助更多人使用这个很棒的工具。

历史

  • 由于在此处发布的评论而创建了本文:Complete Control Over Views
  • 在引言中增加了更多关于该类优势的信息。
© . All rights reserved.