.NET中的强类型控件

时间:2008-12-01 16:34:13

标签: c# .net winforms generics

我正在开发一个Windows窗体应用程序已经有一段时间了,而且我发现自己在GUI代码中做了比在基础业务代码中做的更多的类型转换。

如果你看ComboBox控件接受一些模糊的“对象”作为它的项目,我的意思就变得明显了。 然后你会离开并显示一些DisplayMember和ValueMember等等。

如果我想稍后检索该值,我需要将我的对象强制转换回原来的状态。就像字符串获取值一样

string value = (string)combobox1.SelectedItem;

由于框架中存在泛型已有相当长的一段时间了,我仍然想知道为什么在地狱中,标准工具箱中没有一个控件是通用的。

我也发现自己一直在ListViewItems上使用.Tag属性来保留显示的域对象。但每次我需要访问该对象时,我需要另一个类型转换。

为什么我不能用ListViewItem类型的项创建一个ComboBox或ListView

我在这里遗漏了什么,或者这只是通过控制措施未能完美考虑的另一个例子?

6 个答案:

答案 0 :(得分:3)

虽然对“不使用泛型”的批评不能公平地应用于它们存在之前开发的控件......但是必须对WPF控件感兴趣(.NET 3.0中的新增功能,在.NET 2.0中的泛型之后)。

我在AddChild中查看了ComboBox方法。它需要一个对象参数(ugh)。

此控件主要用于XAML。这样做是因为无法在XAML中指定类型参数吗? (除此之外,是否无法在XAML中指定类型参数?)

很抱歉没有明确的“为什么”回答,只是分享了在使用UI时需要投射的常见痛苦。

答案 1 :(得分:1)

我不认为你错过任何东西。 只是因为这些类是在Generics之前的日子里创建的,而WinForms对于MS花费大量时间来改变或扩展API来说并不是一个前沿。

答案 2 :(得分:1)

我经常为控件创建包装类。这允许我使用泛型。这通常与Reflection结合使用,它在编译时不是类型安全的,但可以在运行时。

答案 3 :(得分:1)

我认为,这个问题的一个常见原因并不是将您的视图/表示逻辑与内存数据模型逻辑分开。遗憾的是,这是WinForms和Visual Studio GUI设计者共同参与的架构错误。

WinForms和VS设计者不鼓励程序员将数据对象的管理与表单类本身分开。如果ComboBox ListViewItem对象不通过泛型或对象集合提供对任意对象的任何支持,那可能会更好。

除非您将有限使用和生命周期的内容混合在一起,否则应尽量避免在控件或表单中存储对单个数据对象的引用。它们应该单独管理,如果需要引用它们,则应该通过为您正在使用的特定类型的视图类设计的模型管理类来完成。

问题的一个简单的绷带可能是使用Form类上的Dictionary字段成员将您放入ComboBox或ListView的文本表示“映射”到原始对象。它不是一个理想的解决方案,但在数据和UI控件之间至少提供了一半间接的间接,这可以使您的代码更易于维护。

编辑:这无疑与暴露对象实例的ListViewItemCollection类是分开的......官方防御很可能是他们想要支持标准的IEnumerable和ICollection接口。但是他们没有理由不提供这些方法的特定于类型的覆盖,因为它是专门设计用于存储ListViewItem实例的。所以在这个特定问题上我没有答案。

答案 4 :(得分:1)

好吧,如果您将控件数据绑定到DataBindingSource,您可以通过这种方式获取数据,但AFAIK仍然没有强类型。如果您正在显示单个业务对象的多个参数/方面,您可以绑定到那个,然后访问(强类型)成员 - 当然,这一切都可以追溯到Turbulent Intellect的答案,这是模型和视图。不过,我同意基于通用的打字会有所帮助。

答案 5 :(得分:1)

有可能(如果您愿意,可以制作自己的通用控件),但是如果您这样做,Visual Studio附带的表单设计器会很烦人。如果没有它,你将不得不做的事情。

你并不是第一个想到这一点的人,微软已经因此受到了公众的批评。让我们希望他们在未来为此增加支持。