使用C#可视化派生类

8
我有一个基类(代表实际装满小球的容器),还有一些派生类。这很好用。
我的问题是如何进行它们的可视化。我有一个UserControl来展示基类。最好的解决方案是为每个派生类都有一个派生的UserControl吗?还是只需要一个可以适用于所有派生类的UserControl更好?
编辑:
显然我没有说得够具体。外观始终相同:矩形内有很多圆圈。不同之处在于填充容器的方式。一种类型在中心放置种子,并以树状结构创建其他球体 - 在这种情况下,应该绘制父项和其子项之间的连接线。
通常,应保持类的可视化效果一致,每个派生类型都有一些特殊之处。

5
你是否正在参加一个计算果冻豆数量的比赛? - James Curran
1
我认为这是软件工程中非常重要的问题;我遇到过类似的情况,但从未真正知道如何妥善解决。很遗憾迄今为止所有的答案都没有抓住重点。 - Timwi
2
@James Curran:有点类似。只不过没有参赛者,而是用空心玻璃微球代替了果冻豆。 - Lukas
9个回答

1

这实际上取决于派生类的显示是否与基类非常相似。如果派生类的显示与基类非常相似,则只需要一个UserControl来进行可视化。另一方面,如果每个派生类都需要显示独特的内容,则最好为每个派生类单独创建一个UserControl来进行可视化。

没有更多关于您的类的具体信息,我无法提供更具体的建议。

编辑: 根据您提供的额外信息,我会建议您创建一个基本的显示类,用于绘制共同的矩形容器,然后创建派生的UserControl以处理绘制每种特定类型的内容。


我同意修改后的答案。让你的基类完成所有绘图工作,派生一个类并覆盖那些在类型之间发生变化的方法。你可以在基类中有一个通用循环,调用一个“绘制下一个”方法,在子类中进行重写。 - Larry Smithmier

0

我认为只有您能够明确回答这个问题。对于给定子类的用户界面可能是您想要的,但如果子类之间仅略有不同,您可能会发现在较少的用户控件中添加一些条件逻辑更容易。我认为这个问题并没有一个正确的答案。


0

仅凭模糊的描述很难说。我们至少需要知道派生类之间有什么区别。

通常情况下,如果了解有限,我会选择每个派生类一个派生UserControl。


0
如果派生类的可视化效果没有区别,那么请务必使用一个UserControl。这里的主要观点是DRY。

0

解决这个问题的一种方法是按照MVVC的视角进行分解:

您需要一个UserControl作为View。

一个基础Painter,作为ViewModel处理您的“带圆圈的框”,派生的Painters实现不同的对象定位逻辑和它们之间的互连关系。

如果您的对象外观可能会变化,则应该通过Adapter模式将它们本身作为ViewModel提供给Painter。

最后,您的圆圈、矩形和与它们相关联的项目是Model。

一般来说:

View(UserControl) -> ViewModel(Painter + 派生的Painters + 对象ViewModel) -> Model(圆形、矩形等)


0
我不完全理解你的问题领域,但我认为你需要进一步拆分它。将你的模型分解成部分,并为每个部分编写视图,然后你可以将它们连接起来。
我会为你的球体编写一个视图,为球体之间的线条编写一个视图,为包含所有内容的矩形编写一个视图,然后每个模型都将负责安排这些并创建相应的SphereModels和LineModels(以及其他所需的内容), 然后你的主视图只需要负责在框中布置这些。
记住始终优先使用组合而不是继承!专注于将你的问题分解成更小的部分。
祝你好运。

0

我认为我会使用一个基础的Visualizer类,其中包含一些用于绘制圆和线条的受保护方法,以及可能是绘图表面(Canvas?)的一些属性,以便每个实现都可以计算基于测量的位置等。

基类实现了所有必要的接口方法/属性,使其成为可视化器。

在IDE调用您的可视化器应该绘制自身的方法中使用策略模式...该方法的实现可以清除画布,设置刷子和其他每个实现都共有的东西-然后调用基类的抽象方法,实际上将圆形/框/线条等放置在画布上。

这样,每个特定的实现只需要担心根据其规则正确定位内容的逻辑-所有“在画布上绘制东西”的工作都保存在基类中。

希望对你有所帮助

编辑:更正了可能会引起混淆的错别字,我在意思是“可视化器”时使用了“控件”这个词。


0

这似乎是一个有多个解决方案的情况。

其中一种方法是设置UserControl来调用基类中的虚拟方法,然后在派生类中覆盖它。在派生类中,您可以只调用基本实现来初始化框架。

您还可以将其设置为以层形式呈现(容器层,球体层,线条层等),并使子类呈现任何独特的层,并确定顺序。这可能很昂贵,但如果大部分图像保持不变,则可以平滑视觉效果。

另一种方法是使用委托而不是继承,但这往往会变得混乱。由于性能惩罚,这通常不是一个好主意。然而,它具有运行时灵活性的优点。根据代码的其余部分,您可能能够在此模型中在中途切换增长样式。如果您认为自己不会利用这种灵活性,我建议您使用不同的模型。

无论使用哪种方法,我建议基类提供共同的绘制程序,以确保一致性。基类中的例程应该由大多数子类使用,但并非所有子类都必须使用。这通常会导致更易管理的代码(除非您最终得到一个10000行文件),更少的错误和更少的努力。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接