3

我是用户控件的新手,到目前为止只创建了一个,所以请耐心等待。我今天一直在阅读,用户控件应该是自包含的,不依赖于父容器中的任何信息。我明白了那部分,但我无法理解的是围绕该原则设计我的程序的“正确”方式。

我正在用 C# 制作一个 Web 表单,其中有一个页面,该页面中有一个用户控件。我已经在它的 ascx 文件中创建了 usercontrol 并将它拖到我的 aspx 页面中。用户控件是一对日期框和一个网格视图,用于显示 SQL 存储过程的结果。

我真的很想重用这个控件,但我不知道如何“告诉”用户控件我想为我所在的特定页面运行什么存储过程而不违反“不要依赖父容器”规则。

谢谢

4

6 回答 6

6

不依赖父容器不代表不能交流。在父级将设置的用户控件中公开一个属性。但是有一个默认值,所以它不会崩溃。

此外,如果这是一个非常具体的控件,那么依赖父级没有理由不好。这可能并不理想,但您将使用用户控件来提供代码分离。

于 2009-05-05T20:59:11.423 回答
2

你的控件不需要知道它的数据来自哪里。它不需要知道存储过程或其他任何事情。它只需要知道它需要显示的数据。如果我理解您的控制权,它是一个带有一些日期过滤器的网格。它将接收数据,显示该数据并按日期过滤。没关系,它只需要知道它需要显示的数据,也许还有父级的默认开始和结束日期。

于 2009-05-05T21:00:22.450 回答
2

如果您不允许用户控件与其父级通信,您将错过用户控件的真正力量。我认为在这种情况下你可能把封装做得有点过分了。

假设您有一个用户控件,它只是一个表格或各种用户数据的网格视图。不可避免地,用户控件需要知道用户的唯一标识符,以便从任何地方提取其数据,这当然会迫使您创建父页面可以设置的公共属性。

另外,请记住,有时用户控件中的操作需要触发父控件上的操作。事件委托在这里发挥了作用,它们非常有用,在我看来,它使用户控件更加有用。

只需放弃关于用户控件和父母不来回交谈的整个想法,您会发现事情变得容易得多。

于 2009-05-05T21:23:50.757 回答
0

所以你在这个用户控件中有一些东西可以将数据绑定到存储过程返回的数据集?

这是处理它的一种方法:与其尝试将存储过程传递给用户控件,不如使用户控件依赖于用户控件的公共属性的数据集。

在运行时,用户控件之外的代码将运行适当的存储过程,并将用户控件上的数据集属性设置为存储过程返回的结果。

于 2009-05-05T20:57:45.157 回答
0

正如其他人所指出的,您的用户控件需要有一种标准的方式来传达其意图和行为。这并不意味着您必须拥有对容器的引用,因此知道 (MyPage.aspx) 实际包含什么。

在使用用户控件时,我发现必不可少的是事件。了解事件以及如何使用它们。事件是交流行为的好方法。

在您的示例中,我可能会将您的条件(日期文本框)拆分为自己的用户控件。创建一个继承自 EventArgs 的新类,其中包含您的条件(DateTime字段)。当用户单击搜索时,EventHandler<YourEventArgs>使用您的自定义触发一个事件(类型)EventArgs。该页面将处理事件,查询数据库,然后将结果传递给您的第二个用户控件上的公共或内部方法,该方法显示记录。

这里的关键,如果您需要调用不同的存储过程,您的标准控件可以在不同的页面上重用。想想插入与更新场景。很多时候,UI 元素是相同的。您可以创建一个控件并在具有两种不同行为(AddRecord.aspx 和 UpdateRecord.aspx)的两个不同页面上使用它。此外,显示记录的控件很容易重用。

一个巨大的好处是您的页面和控件变得相当小。每个控件/页面实际上只关心其一小部分功能。您的代码将变得不那么令人生畏并且更易于维护。

于 2009-05-06T04:40:27.370 回答
0

“告诉”用户控件我想运行什么存储过程

听起来您正在寻找事件/委托
让控件公开一个事件,并让父级添加一个处理程序(也许在构造函数中,如果您想强制它添加一个且只有一个事件)
或者,您可以使用 Command /策略模式 - 让父封装方法,并将封装对象发送到其构造函数中的控件。

于 2009-05-06T04:43:41.980 回答