[转]Custom Controls in Visual C# .NET-如何实现自定义控件
2015-07-25 22:06
627 查看
A very simple introduction to writing your first .NET control
Download source files - 1 Kb
There are two types of components, Visible components (such as a edit box, list control) and non-visible (such as timers, communication, and data access).
This article will concentrate on the creation of a visible component, however the concepts do apply to non visible controls as well.
Here is the minimum code to produce the most basic visible control that functions correctly (but doesn't actually doanything).
Now, if you ask me, this is a lot more straight forward than any OCX control I have ever written (ATL or not).
The control above, since it is derived from
Since the control has no paint routine - yet - it will only erase its background to its parents background color, so it is not too useful at this point. Adding a simple paint routine is also quite simple.
The code above will paint the control using its
Notice that
So, first I must add a data member to hold the properties value. Since the property is a color it will be of type
Next the declaration for the
Since properties are set and retrieved indirectly (which is quite different from reading and writing to data members), other code can be added to the
To make a control easy to use during design time, many controls group their properties and have help strings that display when the property is selected in the property browser. This can also be easily accomplished through the use of attributes. Attributes are special objects that are added above the declaration of a class, function, enum or property, and are delimited by ‘[‘ and ‘]’.
The attributes above cause this property to show up in a
In this example the function
Since the timer class fires an event, you will notice the code required to use an event is quite basic, however I will explain how events work later on.
When the event fires it will call the specified function, this is where the angle is updated and a
The Timer class has an event member called
So to tell the timer to call the event handler
To create your own event here is what to do.
First declare the interface of the event (its required parameters and return type), then make an instance of this type. Note the use of
The code above adds an event list
To actually fire an event you need to first check that your event is non-null, and then fire the event using the following:
Simple! So now you have your first control that has methods, properties and events.
The complete source code is below:
原文连接:着重推荐,仔细学习。
http://www.codeproject.com/Articles/837/Your-first-C-control
http://www.akadia.com/services/dotnet_user_controls.html#Login%20Validation%20User%20Control
Download source files - 1 Kb
Introduction
This is an extremely simple introduction to creating a control, adding methods and properties, and adding event handlers.There are two types of components, Visible components (such as a edit box, list control) and non-visible (such as timers, communication, and data access).
This article will concentrate on the creation of a visible component, however the concepts do apply to non visible controls as well.
Visible Components
A visible component is any class derived from eitherSystem.WinForms.Controlor
System.WinForms.RichControl.
Here is the minimum code to produce the most basic visible control that functions correctly (but doesn't actually doanything).
//specify the namespace in which the control resides namespace Test.Control { //specify the name spaces of other classes that are commonly referenced using System.WinForms; //the control definition and implementation public class MyControl : System.WinForms.RichControl { } }
Now, if you ask me, this is a lot more straight forward than any OCX control I have ever written (ATL or not).
The control above, since it is derived from
RichControl, contains quite a bit of stock functionality including: stock properties, stock events, layout management, the ability to act as a full control container (for child controls), and more. In other words, just start writing in your business logic, all of the grunt work is taken care of.
Since the control has no paint routine - yet - it will only erase its background to its parents background color, so it is not too useful at this point. Adding a simple paint routine is also quite simple.
using System.Drawing; protected override void OnPaint(PaintEventArgs pe) { SolidBrush b = new SolidBrush(this.BackColor); pe.Graphics.FillRectangle(b,this.ClientRectangle); }
The code above will paint the control using its
BackColorproperty. So if you add this control to a form now and modify its
BackColorpropery via the property sheet the control's color will now change as well.
Notice that
using System.Drawing;has been added. This allows classes such as
SolidBrushto be used without specifying the entire namespace (
System.Drawing.SolidBrush).
Adding a property
Adding a read/write or read only property to a control is also quite straight forward. In this example I am going to add a set of gradient color properties to the control. Below I am only going to show one of the properties, since the other is a mirror copy of the first, except for the variable name.private System.Drawing.Color gradColor1; public System.Drawing.Color Gradient1 { set { this.gradColor1 = value; } get { return this.gradColor1; } }
So, first I must add a data member to hold the properties value. Since the property is a color it will be of type
System.Drawing.Color. Since
using System.Drawing;has been added the variable can also be declared as just
Color.
Next the declaration for the
Gradient1property is made. The start of the declaration looks similar to a function declaration (access modifier, return type, and name). Although the property itself is not a function it can contain two special functions nested within it:
setand
get. To make a read/write property both
setand
getmust be implemented. For a read-only property just implement
get. Even though the
setfunction does not have a parameter list, it does get passed a special parameter called
value. The type of the
Valueparameter will always be the same type as the property itself.
Since properties are set and retrieved indirectly (which is quite different from reading and writing to data members), other code can be added to the
setand
getfunctions. For instance if a property is a calculated value, the calculation can be performed within the
getitself. During a
setit is possible to set flags or cause the control to refresh itself, etc.
To make a control easy to use during design time, many controls group their properties and have help strings that display when the property is selected in the property browser. This can also be easily accomplished through the use of attributes. Attributes are special objects that are added above the declaration of a class, function, enum or property, and are delimited by ‘[‘ and ‘]’.
[ Category("Gradient"), Description("First Gradient Color") ] public System.Drawing.Color Gradient1 { set { this.gradColor1 = value; } get { return this.gradColor1; } }
The attributes above cause this property to show up in a
Gradientproperty group and will display "First Gradient Color" as a help string at the bottom of the property browser when selected.
Adding a method
Adding a method is the same as adding any other function. In fact a function and method are essentially the same in the .Net world. If you do not want the function exposed to the outside just make sure its access modifier is set to protected or private. This is not to say that all your public functions can be used by anyone, you have quite a bit of control over the use of your functions … but that is another topic.public void StartRotation(bool state) { ... }
In this example the function
StartRotationwill be added, which will rotate the angle of the gradient based on a timer.
private System.Timers.Timer rotateTimer = null; public void StartRotation(bool state) { rotateTimer = new System.Timers.Timer(); rotateTimer.Tick += new EventHandler(OnTimedEvent); rotateTimer.Interval= 500; rotateTimer.Enabled = true; } public void OnTimedEvent(object source, EventArgs e) { gradAngle += 10; if(gradAngle > = 360) { gradAngle = 0; } this.Refresh(); }
Since the timer class fires an event, you will notice the code required to use an event is quite basic, however I will explain how events work later on.
When the event fires it will call the specified function, this is where the angle is updated and a
Refreshis requested.
Using and Adding Events
In the previous section code was added that used a timer event.rotateTimer.Tick += new EventHandler(OnTimedEvent);
The Timer class has an event member called
Tickthat handles a list of event listeners. Since an event can have more than one listener the
+=is used to assign the event.
So to tell the timer to call the event handler
OnTimedEventjust create a new event handler, pass in the function name into the constructor and assign that to the Timers event list. Any number of event handlers can be added to a single event. Note, the order in which the handlers are called is not defined.
To create your own event here is what to do.
First declare the interface of the event (its required parameters and return type), then make an instance of this type. Note the use of
delegate.
public delegate void angleChange(); public event angleChange OnAngleChange;
The code above adds an event list
OnAngleChangethat can be used to add an event in the following manner
MyControl ctrl = new MyControl(); ctrl.OnAngleChange += new MyControl.angleChange(OnMyEvent); public void OnMyEvent() { MessageBox.Show("Event Fired"); }
To actually fire an event you need to first check that your event is non-null, and then fire the event using the following:
if (OnAngleChange != null) { OnAngleChange(); }
Simple! So now you have your first control that has methods, properties and events.
The complete source code is below:
//specify the namespace in which the control resides
namespace Test.Control
{
//specify the name spaces of other classes that are commonly referenced
using System;
using System.Collections;
using System.Core;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.WinForms;
using System.Timers;
//the control definition and implementation
public class MyControl : System.WinForms.RichControl
{
private System.Drawing.Color gradColor1;
private System.Drawing.Color gradColor2;
private int gradAngle = 0;
private System.Timers.Timer rotateTimer = null;
public delegate void angleChange(); public event angleChange OnAngleChange;
private void InitializeComponent ()
{
}
public MyControl()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
LinearGradientBrush b = new LinearGradientBrush(this.ClientRectangle,
gradColor1, gradColor2,gradAngle,false);
pe.Graphics.FillRectangle(b,this.ClientRectangle);
}
public void StartRotation(bool state)
{
rotateTimer = new System.Timers.Timer();
rotateTimer.Tick += new EventHandler(OnTimedEvent);
// Set the Interval to 5 seconds.
rotateTimer.Interval=500;
rotateTimer.Enabled=true;
}
public void OnTimedEvent(object source, EventArgs e)
{
gradAngle += 10;
if(gradAngle >= 360)
{
gradAngle = 0;
}
this.Refresh();
if(OnAngleChange != null)
{
OnAngleChange();
}
}
[ Category("Gradient"), Description("First Gradient Color") ] public System.Drawing.Color Gradient1 { set { this.gradColor1 = value; } get { return this.gradColor1; } }
[
Category("Gradient"),
Description("Second Gradient Color")
]
public System.Drawing.Color Gradient2
{
set
{
this.gradColor2 = value;
}
get
{
return this.gradColor2;
}
}
}
}
原文连接:着重推荐,仔细学习。
http://www.codeproject.com/Articles/837/Your-first-C-control
http://www.akadia.com/services/dotnet_user_controls.html#Login%20Validation%20User%20Control
相关文章推荐
- C#-默认显示前列-ShinePans
- c# 阶段总结
- c#中的委托
- c# BackGroundWorker 多线程操作的小例子
- c#中的程序集
- 自定义ComboBox控件,完美解决C#自带的ComboBox效率慢的问题
- 设置C# Windows 服务与桌面交互
- C# 配置错误定义了重复的“system.web.extensions/scripting/scriptResourceHandler”节
- C#学习笔记(十六):Attribute
- c# 多线程 调用带参数函数
- C#生成随机数
- C#中Split用法
- C#字母与ASCII码的转换
- C# 实现Tree,包含parentId和children
- C# using 三种使用方式
- C#中的反射
- C#中对泛型List进行分组输出元素
- C#实现WinForm随WINDOWS服务一起启动
- C#调用Rar文件及获取Rar返回值的方法
- C#群发邮件