首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

继承抽象基类的窗体无法打开UI设计器的有关问题

2012-12-20 
继承抽象基类的窗体无法打开UI设计器的问题问题截图如下:我想实现的效果说明:1、在基类中把按钮的位置放置

继承抽象基类的窗体无法打开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);



            return base.GetReflectionType(objectType, instance);
        }
        public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
        {
            if (objectType == typeof(Form1))
                objectType = typeof(Form4VS);

            return base.CreateInstance(provider, typeof(Form4VS), argTypes, args);
        }
    }



3:在抽象版本的类上加注特性
 
 [TypeDescriptionProvider(typeof(AbstractCommunicatorProvider))]
    public abstract  partial class Form1 : Form


这样基本可以解决vs设计器不能加载界面的毛病,注意我自己测试的结果比较有古怪,vs2010 net3.5 环境编译后并不能立刻就显示UI,我得把vs关闭后重新打开才能看到效果。
另外:我也测试了一下vs2012并不需要做上面的处理,他本身就支持抽象UI类的继承
[其他解释]
话说回来,这样弄完了,也只是解决你的vs不能显示他的毛病,你说的第二个自动添加代码还是不好办

所以总体上还是建议,直接使用定制vs项模版要来的便捷的多,定制方法:vs-文件-导出模版-选择项模版,然后安装向导一步一步来就成了,1分钟内就可以搞定(简单快速,唯一的毛病就是如果是团队开发,就是你的把生成的东西发布到公用位置,然后让其他团队成员导入这个项模版)
[其他解释]
感谢 caozhy版主,感谢wanghui0380老兄我想等到周一晚上结贴,看看还有没有其他思路,扩展下自己的思路,呵呵,怕帖子结了没人回复了,还请两位担待一下
[其他解释]
引用:
或者你把那些抽象方法做成一个接口,让子类去实现。


做成接口让子类去实现没有问题,但是我不知道怎么在父类中调用子类实现的接口的方法,开始是在父类的构造函数中接受一个接口类型的参数,但是在子类中我不知道如何把这个参数传递到父类中
[其他解释]
现在通过一个绕弯的方式实现了通过接口达到这种效果,把在父类的构造函数中接受一个接口类型的参数的方式改为在父类中定义一个虚方法,然后在虚方法中给接口私有变量赋值,然后在子类中实现接口并且在子类的构造函数中调用基类的虚方法,代码及界面如下:





[其他解释]
public partial FormEdit{
    private Form baseForm; 
    public FormEdit(Form pForm){
        baseForm = pForm
        ......
        }
[其他解释]
学习思路。。。
[其他解释]
当使用MVC设计模式时,根本就不需要UI设计器,也无法使用UI设计器,
原因在于:设计时刻开发者不知道UI上的内容,
这完全由ViewModel和BusinessModel决定,
由ViewController在运行时刻动态渲染

[其他解释]
实际编写为一个可实例化的对象类就行了。基类已经实现的,并且子类不需要重写的,子类就不需要重写。

你为什么硬要子类去重写呢?
[其他解释]
采用定制项模板的方法挺方便用的,之前还真不知道,非常感谢,呵呵

热点排行