继承抽象基类的窗体无法打开UI设计器的问题
问题截图如下:
我想实现的效果说明:
1、在基类中把按钮的位置放置好,避免子类重复设置按钮
2、在基类中把各个按钮的单击事件注册好,避免在子类中重复设置按钮的单击事件
3、在基类中定义每个按钮单击事件调用的抽象方法,这些抽象方法是需要子类去实现的,这样子类一继承基类就自动生成了各个需要实现的抽象方法的架构,直接将需要的代码填充到相应的方法中就可以实现相应的功能了,考虑过不用抽象方法,而是使用虚方法,但是使用虚方法继承的时候不能自动把各个需要重写的方法填充到代码区中,需要人为自己指定重写哪个方法,这样一是输入量稍微多一些,二是如果一旦重写的方法不完全就会有一些功能实现不了,也考虑过用基类继承接口的方式把方法写到接口中,但是没有找到什么办法能够做到我需要的效果,代码及界面截图如下,不知道我想要实现的效果怎么能够做到,或者说这种效果能够做到不。
------最佳解决方案-------------------- 如果你想完全自动的实现,我个人是定制项模版完成,有时候我也会用T4模版引擎完成
ps:其实如果要求不高,你还可以在基类的方法写 throw new NotImplementedException("功能必须在子类实现");
这样如果子类木实现方法,则会弹出尚未实现的异常,这样可以强制程序员必须去实现方法
------其他解决方案-------------------- 或者你把那些抽象方法做成一个接口,让子类去实现。
------其他解决方案-------------------- 引用: 如果你想完全自动的实现,我个人是定制项模版完成,有时候我也会用T4模版引擎完成
ps:其实如果要求不高,你还可以在基类的方法写 throw new NotImplementedException("功能必须在子类实现");
这样如果子类木实现方法,则会弹出尚未实现的异常,这样可以强制程序员必须去实现方法
我觉得让调用的程序员看到错误抛出,才刺激他去实现实在那个——而且不可靠。因为如果这些方法是内部调用,那么设计器一样会出错。如果这些方法不是窗体内部调用,而是外部的方法,那么程序员往往无法感知到这个错误,如果没有客户端去调用的话。
------其他解决方案-------------------- public partial class View : Form {
//你可以根据自己的场景,重载带参数的构造函数
public View() : base() {
//...此处忽略变量声明
object[] _args = new object[]{this};
//当前form引用被传入业务逻辑组件的构造器
ViewModel = System.Activator.CreateInstance(_assName, _className, false, 0, null, _args, null, null);
}
------其他解决方案-------------------- “在基类中定义每个按钮单击事件调用的抽象方法,这些抽象方法是需要子类去实现的”
不懂!如果自来不去“实现”,程序运行中会出错吗?
------其他解决方案-------------------- 不要使用抽象基类。将抽象方法写成虚拟方法,并且留空即可。
------其他解决方案-------------------- 感谢 caozhy版主的回复,我是觉得使用虚方法,继承的时候不能自动把各个需要重写的方法填充到代码区中,需要人为自己指定重写哪个方法,这样一是输入量稍微多一些,二是如果一旦重写的方法不完全就会有一些功能实现不了这种情况,如果我上面的效果实在实现不了的话就只能选择虚方法的方式了,呵呵
------其他解决方案-------------------- 额,ls说滴的确是个问题,我刚刚自己试验了一下,可以这样“欺骗”一下vs
1.先把这个窗体复制一份,更名为Form4VS(去掉抽象,同时改类名)
2.
using System.ComponentModel;
//我这里form1表示你的原始抽象类,Form4VS表示相同实现的非抽象版本
// 基本含义就是利用TypeDescriptionProvider提供去欺骗vs,让vs在加载form1的时候去使用那个非抽象版本
public class AbstractCommunicatorProvider : TypeDescriptionProvider
{
public AbstractCommunicatorProvider()
: base(TypeDescriptor.GetProvider(typeof(Form1)))
{
}
public override Type GetReflectionType(Type objectType, object instance)
{
if (objectType == typeof(Form1))
objectType = typeof(Form4VS);