C#中自定义控件隐藏基类成员(属性、方法和事件)的方法
2013-10-12 11:33
387 查看
编写自定义控件时,总是继承C#中提供的Control类,而Control类是C#中所有窗体控件的基类,里面定义了大量的属性、方法和事件,而很多基类成员在自定义控件中可能不需要,因为编写者会希望在自定义控件中隐藏这些成员,避免使用者调用这些成员。
从面向对象的角度来看,不允许调用子类者访问其基类的公共成员是不可能的,我们不可能去掉或者改写基类的公共成员,即使基类成员是抽象的或是虚的,重写时也不可能修改其可访问性。
即然不能做到真正的“去掉”不需要的基类成员,那我们只能另想办法了。实际上C#中的PictureBox就是一个很好的例子,在代码编辑器中,你在智能感应器中是找不到PictureBox的Text属性的,但是如果你强行写一行:pictureBox1.Text="aaa";这样的代码,编译器也不会报错。显然,Text是基类Control的属性,PictureBox仍然继承了它,并且可以访问它,只是使用者无法通过智能感应器访问,在设计时的属性窗口中也找不到它而已,事实上实现这一点就够了。
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
以上这段代码就是实现这个目的。重写基类Text属性,BrowsableAttribute定义该属性不在属性浏览器中显示,EditorBrowsableAttribute则定义该属性不在智能感应器中出现。
对于不能重写的基类成员,也可以用new的方式隐藏基类成员。下面代码隐藏了TextChanged事件
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler TextChanged;
protected override void OnTextChanged(EventArgs e)
{
if (TextChanged != null)
TextChanged(this, new EventArgs());
}
事实上不需要重写OnTextChanged方法,不过由于我们重新定义的TextChanged事件从未被调用,编译器会给出一个警告,而且万一哪个调用者强行使用此事件,程序将会报错,所以还是写上的好。
我写自定义控件时就碰到这个问题,网上搜索一遍,照例无结果(为啥要说照例……),只得自己花点时间弄一下,记下来免得以后又忘了。
比较有趣的是,在搜索的过程中,去了MSDN的中英文论坛,有人提过这个问题,而版主的回答无一例外是不能实现,只能用BrowsableAttribute在属性浏览器中隐藏……其实我一度也想放弃,因为从面向对象的角度来看,这些版主的回答并没错误,要不是突然想到PictureBox控件,还真以为实现不了了……事实上我没什么耐心,要是早把System.ComponentModel下所有的Attribute类全部仔细看一遍(开始是看过,不过是一目十行这么看下来的……)也就不需要去网上搜索一圈无结果,再回来老老实实看文档了。
从面向对象的角度来看,不允许调用子类者访问其基类的公共成员是不可能的,我们不可能去掉或者改写基类的公共成员,即使基类成员是抽象的或是虚的,重写时也不可能修改其可访问性。
即然不能做到真正的“去掉”不需要的基类成员,那我们只能另想办法了。实际上C#中的PictureBox就是一个很好的例子,在代码编辑器中,你在智能感应器中是找不到PictureBox的Text属性的,但是如果你强行写一行:pictureBox1.Text="aaa";这样的代码,编译器也不会报错。显然,Text是基类Control的属性,PictureBox仍然继承了它,并且可以访问它,只是使用者无法通过智能感应器访问,在设计时的属性窗口中也找不到它而已,事实上实现这一点就够了。
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override string Text
{
get { return base.Text; }
set { base.Text = value; }
}
以上这段代码就是实现这个目的。重写基类Text属性,BrowsableAttribute定义该属性不在属性浏览器中显示,EditorBrowsableAttribute则定义该属性不在智能感应器中出现。
对于不能重写的基类成员,也可以用new的方式隐藏基类成员。下面代码隐藏了TextChanged事件
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler TextChanged;
protected override void OnTextChanged(EventArgs e)
{
if (TextChanged != null)
TextChanged(this, new EventArgs());
}
事实上不需要重写OnTextChanged方法,不过由于我们重新定义的TextChanged事件从未被调用,编译器会给出一个警告,而且万一哪个调用者强行使用此事件,程序将会报错,所以还是写上的好。
我写自定义控件时就碰到这个问题,网上搜索一遍,照例无结果(为啥要说照例……),只得自己花点时间弄一下,记下来免得以后又忘了。
比较有趣的是,在搜索的过程中,去了MSDN的中英文论坛,有人提过这个问题,而版主的回答无一例外是不能实现,只能用BrowsableAttribute在属性浏览器中隐藏……其实我一度也想放弃,因为从面向对象的角度来看,这些版主的回答并没错误,要不是突然想到PictureBox控件,还真以为实现不了了……事实上我没什么耐心,要是早把System.ComponentModel下所有的Attribute类全部仔细看一遍(开始是看过,不过是一目十行这么看下来的……)也就不需要去网上搜索一圈无结果,再回来老老实实看文档了。
相关文章推荐
- (原创)c#学习笔记10--定义类成员02--类成员的其他议题01--隐藏基类方法
- (原创)c#学习笔记10--定义类成员02--类成员的其他议题02--调用重写或隐藏的基类方法
- 再论属性可以变成方法---C#中使用new关键字隐藏成员
- C# 类的属性,方法,事件
- C#中combobox 和TreeView控件属性、事件、方法收集
- C#继承机制 访问与隐藏基类成员
- 关于C#做出的小程序的调试细节 及 visible属性和几个C#中的事件方法
- C#继承---基类虚方法virtual,派生类隐藏方法new
- C#继承类重写与隐藏基类方法的区别
- IHTMLDocument2的所有成员、属性、方法、事件
- c# 类成员的定义 定义方法、字段和属性
- 【C#基础】之WinForm窗体常用控件的属性、方法及事件简介
- javaScript事件学习小结(四)event的公共成员(属性和方法)
- c#隐藏和重写基类方法的异同
- C#继承类重写与隐藏基类方法的区别
- [Unity&C#&继承]unity继承中覆盖和隐藏基类成员变量 string 变量
- IHTMLDocument2的所有成员、属性、方法、事件[转]
- c#隐藏和重写基类方法的区别
- 【C#基础】之WinForm窗体常用控件的属性、方法及事件简介
- C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性)