c# - 根据模型类型为视图选择不同的图形
问题描述
介绍
我正在构建一个相对简单的程序来设计穿孔板上的布局(简单的 diy 友好电路板)。我正在使用 WinFormsSystem.Drawing
绘制电路板。我需要能够序列化代表 perfboard 及其组件的模型的相关部分。
TL;博士
- 我有不同类型的模型(不一定是类中的类型)
- 我的观点需要某种方式来决定使用哪种图形(图像/绘图例程),具体取决于该类型。
- 这通常如何在 MVC/MVVM/其他中完成?
- 我想避免类型检查或将
ComponentType
属性存储为字符串/枚举。 - 模型需要可序列化(可能是二进制而不是 XML/JSON)。
目标
- 遵循某种模型-视图分离(只需将它们混合在一起就可以解决这个特定问题,但将来可能会引入新问题)。
- 一种实际面向对象的方法,即避免类型检查、将
ComponentType
属性存储为字符串/枚举等。
想法
假设我有一个Component
类,它可以是使用组合继承的类,也可以是由离散类(例如Wire
和)实现的接口Transistor
。然后我需要以Component
某种方式将这些对象绘制到窗口上。一个简单的方法是Draw(System.Drawing.Graphics graphics)
在类上有一个方法,但这会完全打破模型-视图的分离。
如果我在某种程度上遵循 MVC 或 MVVM(或任何真正的分离模式),我将拥有ComponentView
某种(与模型相同:一个组合类或子类)。不知何故,这个视图需要决定它代表什么类型的组件,并根据它选择要显示的图形(可能是一个带有 Draw(System.Drawing.Graphics graphics) 方法的简单界面或其他)。
基本型号
public class Perfboard
{
List<Component> components;
public int Width { get; set; }
public int Height { get; set; }
public IEnumerable Components => components;
public Perfboard()
{
}
public Perfboard(int width, int height)
{
Width = width;
Height = height;
}
// ...
}
public class Component
{
// This will have a position used for the graphic maybe?
// The component's legs needs to be represented either in here, or maybe I build the perfboard
// as a Cell[w,h] array and have the cells refer to the Component...
}
可能的观点
public class PerfboardView
{
public Perfboard Board { get; private set; }
// Either I have a list of ComponentView objects here, or they're just generated on the fly when drawing.
// Basically just X and Y for the cursor and a Draw method
public BoardCursor Cursor { get; private set; }
public PerfboardView(Perfboard board)
{
Board = board;
}
public void Draw(Graphics g)
{
g.TranslateTransform(Cursor.X * -25.4f, Cursor.Y * -25.4f);
DrawHoles(g);
// Somehow draw the components...
Cursor.Draw(g);
}
// ...
}
免责声明
该模型的结构绝对不是一成不变的。我觉得我遗漏了一些明显的东西,所以欢迎使用完全不同的方法!
解决方案
推荐阅读
- ios - 尝试使用分段视图导航视图控制器
- html - 选择列表中的下拉子菜单
- c++ - 如何在 C++ 中创建竞争条件
- angular - 在 Angular 6 项目中使用 2 tslint.json 文件
- angular - 动态注册canDeactivate guard并提示确认导航
- android - Google AdMob - 无法使用统一 sdk,因为“com.google.android.gms:play-services-ads:15.0.1”上不存在 com.android.gms.ads.InterstitialAd
- android - 如何在Android应用程序进入后台时隐藏屏幕信息
- php - 用于电子邮件验证的签名路由未通过签名验证
- r - 传单 setview() 查看县地图
- javascript - 为什么 React 会为同一个 HTML 显示两个不同的高度?componentDidUpdate 是否包含 CSS?