ASP.NET:页面上的所有内容,还是闯入控件?

时间:2009-03-16 18:55:16

标签: asp.net architecture controls

当您制作一个视觉细分到特定区域的页面时,您是将这些区域分解为控件,还是将所有内容放在页面上并放在一个代码隐藏中?

如果区域分为控件,您如何促进控件之间的通信?通过通信我的意思是简单地在服务器端交换数据。

想象一个页面上面有一个相当复杂的GridView上面的几个盒子。一个框指示GridView显示的内容,另一个框允许您使用GridView执行各种操作。两个盒子都需要与网格通信,但不能相互通信。

这个代码隐藏至少需要几千行。

制作这些类型的设计决策的任何资源都会有所帮助。

由于

7 个答案:

答案 0 :(得分:4)

对于我的第一个asp.net应用程序,我使用了单独的控件方法。但是,我不再这样做,现在我采取的方法是将所有内容放在一个页面中。如果您需要在多个页面中重复相同的页面和功能部分,我只会使用控件。重用实际上是控件的用途。

如果要采用多重控制方法,可以在控件上使用属性,方法和/或事件,以允许它们相互通信或与页面上的控件进行通信。

答案 1 :(得分:1)

Usercontrols促进了可重用性,并且它们偶然将功能分解为更小的部分,这可以使代码库更易于管理。您也可以通过使用区域和其他组织技术在一个整体页面上仔细规划代码来实现此目的。

过去我做过两件事,两者都能奏效。我发现进行控制到页面通信的最佳方法是使用事件 - 即给定一个带有BoxA(网格显示),BoxB(网格选项)和网格(带有gridview的用户控件)的页面,BoxA可以定义一个事件“DisplaySettingsChanged”,只要其设置发生变化,它就会在回发期间抛出。托管页面将在不同组件之间创建事件订阅,例如捕获DisplaySettingsChanged并调用Grid.Refresh或其他任何内容。

对于所有额外的基础设施,如果您确定不想在任何地方重复使用任何这些组件,我可能会将其放在一个单一的页面中,特别注意保持一切有组织和可读。< / p>

答案 2 :(得分:1)

您可以使用用户控件的原因有几个,例如:

  • 模块化代码:您可以将代码分区为多个用户控件,而不是一个膨胀的页面类,每个用户控件的代码较少。因此,如果您的页面有太多要管理的代码,将其拆分为用户控件可能会减少每个类的大小。
  • 重新使用:如果一个控件用于多个页面,或者在一个页面上有多个实例,则更容易构建一次,然后重复使用几次。因此,如果您有在许多地方重复使用的常见UI组件,则用户控件可以为您提供帮助。

当然需要付出代价,每个控件都必须公开允许其父容器控制它的属性,并且必须公开事件以通知其父级某些事件发生。父控件也可以公开类似的事件和属性,但这会在用户控件中添加对父控件的依赖,这可能会使控件在其他容器中的重用变得复杂。

如果您可以将页面的许多部分分解为明确定义责任分离的逻辑组件,那么它们是用户控件的理想候选者。它就像你定义类时一样,并且某些类可能变得过于复杂而你决定将它分成几个较小的类,只有这里你定义的每个新类的成本都会更高。

根据我的经验,用户控件非常棒,只是不要将控件分解到如此多的深度级别,以至于您创建的复杂度比原始的膨胀页面更复杂。尝试找到一个快乐的媒介,其中控件做得足够,而不是太多,并且你没有太多的控件。

以下是一些关于用户控制通信的教程 http://www.codeproject.com/KB/user-controls/Page_UserControl.aspx
http://aspalliance.com/1461_Page_and_User_Control_Communication

答案 3 :(得分:0)

控件应该公开事件,页面应该处理相同的事情并相应地更新网格视图。

打破控制纯粹是基于需要。如果你想重用它们将它们分解为控件。如果它像废料项目一样,则不需要特定的控制。

答案 4 :(得分:0)

您可以选择2条路线 -

路线1:从用户/利益相关者/管理/ UAT获得好处,从页面中提取组件以获得更好的可管理性,重用等。

路线2:从一开始就考虑可重复使用的组件。测试组件/用户控件/自定义控件/ Web部件。在网页上混合和匹配您的组件并发送以供批准。

大多数情况下,如果您的要求不断变化并且您没有太多时间,那么您在路线1上应该没有任何问题。您将了解UI需求并分析是否将页面分解为组件,组件是否需要直接相互通信或通过DB等进行通信。

路由2是您确定是否有足够的要求表明某些UI /行为可以重复使用,需要独立测试等。

有时直接跳转到路线2并不容易。如果您有域经验,那么肯定。

现在在ASP.net世界中,您甚至必须在自定义和用户控件之间进行选择。那是你可能要做的另一个决定。

希望这有帮助

快乐编码!!

答案 5 :(得分:0)

如果要重用代码,我只会分成单独的控件。否则只是浪费时间。如果在设计模式下不容易管理html,我也尝试创建服务器控件,例如动态生成面包屑或导航的代码。登录表单可能是用户控件的一个很好的例子。

答案 6 :(得分:0)

我从事过两个极端的项目,从堆积到一个页面的所有功能到具有专用用户控件的所有功能。至少,我建议您执行以下操作:

  • 网站范围的设计属于您的主页
  • 应在两个或多个页面上显示的功能应封装在用户控件中。 (例如,登录控件可能会出现在多个位置。)
  • 其他功能非常适合嵌入您的aspx页面。

棘手的部分是正确的沟通,当您拥有需要相互通信的深层嵌套控件层,或者您需要在子页面上通知控件的控件时,这可能会很困难(如果它们存在)。如果需要在两个或更多级别的控件之间进行通信,请使用以下模型:

                ProxyNotifier
            /                  \
   Control1                      Control2

换句话说,Control1和Control2都可以访问ProxyNotifier实例。 Control1信号ProxyNotifer和ProxyNotifer将信号传递给Control2。

一个非常简单的实现如下所示:(注意:未经测试的代码,不适合生产使用):

public static class ProxyNotifer
{
    // NOTE: This delegate should NOT be held in a static variable since
    // its session specific
    private static Action<string> NotifyEvent
    {
        get
        {
            if (!Session.ContainsKey["ProxyNotifyEvent"])
            {
                Session["ProxyNotifyEvent"] = null;
            }
            return Session["ProxyNotifyEvent"] as Action<string>;
        }
    }

    public static void Subscribe(Action<string> handler)
    {
        NotifyEvent += handler;
    }

    public static void Unsubscribe(Action<string> handler)
    {
        NotifyEvent -= handler;
    }

    public static void Invoke(string msg)
    {
        if (NotifyEvent != null) { NotifyEvent(msg); }
    }
}


public class Control1 : UserControl
{
    void SomethingHappened()
    {
        ProxyNotifyer.Invoke("Hello world!");
    }
}


public class Control2 : UserControl
{
    public Control2()
    {
        ProxyNotifer.Subscribe(Respond);
    }

    // ALWAYS unregister your event when your control is disposed, 
    // otherwise weirdness happens
    public void Dispose()
    {
        ProxyNotifier.Unsubscript(Respond);
        base.Dispose();
    }

    public void Respond(string msg)
    {
        lblMsg.Text = msg;
    }
}

现在,Control1和Control2无论在页面上的什么位置都可以进行通信。