1.C#中 paint()与 Onpaint()关系
百度知道:
paint 是事件 onpaint 方法 onpaint 方法是调用 paint 事件的,用哪一个,
效果是一样,就看那一个方便了内部是这样实现的: protected virtual
OnPaint(PaintEventArgs e){ if(paint !=
null){ paint(this,e);}}如果直接重写 onpaint,paint 就会失效;这
样就不会失效:protected override OnPaint(PaintEventArgs
e){ base.OnPaint(e); //自己的代码}
(一)重绘时候经常会用到 OnPaint()和 Paint,它们有什么区别呢?
1.OnPaint 方法是对一个控件来说的;而 Paint 事件是对一个控件对象来说的。它
们中前者相当于是类的一个成员函数,而后者相当于是类的一个函数指针类型的变量(会因
对象的不同而不同)。
2.OnPaint 方法引发 Paint 事件,所以重写 OnPaint 方法,一定要调用 base.OnPaint,
否则就不会引发 Paint 事件了。OnPaint 原形应该类似以下形式(从中便可以看出):
protected virtual void OnPaint(PaintEventArgs e)
{
if (this.Paint != null)
{
this.Paint(this,e);
}
}
3.从实例中观察二者调用顺序
private void Form1_Paint(object sender, PaintEventArgs e)
{
test t = new test();
t.AntiAlias = true;
t.SetColor(test.eShapeColor.Circle1FillColor,
Color.DarkCyan);
}
e.Graphics.DrawImageUnscaled(t.Image, 10, 10);
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);//引发 Paint 事件处理(处理该事件时候调用
Form1_Paint 方法)
..........
}
Form1_Paint()只是处理 Paint 事件的方法,也可将它的四行代码在 OnPaint
方法中写,此时可以不写 base.OnPaint(e),即不引发事件处理,也可达到同样的效果。
(二)那么应分别在什么情况下使用它们呢?
1.如果想对所有控件都按照某种固定的方式显示,如:自己写控件时,则需要修改
重载控件的 OnPaint 方法;而如果仅仅在某个环境下,对某个对象要做不同的显示,则只需
在其的 Paint 事件中做即可。
2.在实现派生类的时候,遵循 C# 原则 35:选择重写函数而不是使用事件句柄。
许多.net 类库中的类都提供了两种不同的处理事件句柄的方法。既可以为其添加事
件,也可以重写其基类的事件抽象方法。在实现派生类的时候,更好的选择是重写基类中的
抽象方法。
因为这样,一旦事件句柄抛出异常,不会再有其他的事件句柄被调用。这避免了一
些错误代码继续被调用而引发的问题。通过重写受保护的虚方法,我们的句柄可以 第一个
被调用。基类中虚函数负责其他相关句柄的调用。这意味着如果需要调用那些事件句柄(一
般来说是需要的),就要调用基类的虚函数。在有些特殊情况下我 们需要替换基类的默认行
为,可能不需要调用任何原有的事件句柄。虽然我们不能保证所有的事件句柄都被执行,因
为其可能会抛出异常,但是我们可以保证派生类 的行为是正确的。
使用 override 比添加事件句柄高效的多。在 条款 22 中展示了
System.Windows.Forms.Control 类是如何存储句柄时间并将其对应到每一个事件的。这种
事件机制由于要检查事件句柄将造成更多的消耗。事件句柄列表中的每个方法都需要执行。
相比重写虚方法,通过事件处理会消耗更多的时间。
此外,重写虚方法只需要维护一个函数就可以达到检查和修改的目的,代码更清晰。
而事件机制需要两个维护点:事件句柄函数和事件绑定代码。其中任何一点都可能造成整体
功能上的失败。一个函数显然要简单些。
2. 在 VS 中用 C#语言创建 Graphics 对象
c#调用 DLL(VC6.0)
c#创建 Dll 动态链接库、C#使用动态链接库
在 VS 中用 C#语言创建 Graphics 对象
2011-09-06 22:50:40| 分类: c#学习 | 标签: |字号大中小 订阅
1.Graphics g = this.CreateGraphics();//this 可替换成其他的控件名,用 this 的话将 form 创建为画布
2.在 Paint 事件中
Graphics g = e.Graphics;
3.利用 Graphics 类的 FromImage 静态方法(不常用)
Image img=Image.FromFile("g1.jpg");
Graphics g = Graphics.FromImage(img);
在 Paint 事件中,Paint 的成员 PaintEventArgs 类有 Graphics 属性,e 是
PaintEventArgs 类的对象。用对象 e 调用 Graphics 属性。你的 DrawMe 方法中
没有输入参数 PaintEventArgs e,应当用 CreateGraphics 方法创建图形对象:
Graphics g = this.CreateGraphics();
//窗体获取 Graphics 对象的引用
//控件获取 Graphics 对象的引用
Graphics g = control.CreateGraphics();
你这里大概是窗体,因此你的代码改为:
Graphics g = this.CreateGraphics();
g.FillRectangle(blueBrush, x, y, width, height);
就可以了。
如果你想要在 DrawMe 中添加参数 e 为图形对象,DrawMe 应当是某个事件(通
常是 Paint 事件)的处理程序,要声明一个委托和事件,构造事件处理方法,这
个事件处理方法是根据你的委托和事件名称,当你敲+=时系统提示你按 Tap 键,
自动给你加上的,并且参数也是系统给你加上的,一般不自己做,在属性框选择
合适的事件。
3.C# Excel 基本操作小结
1 前言
这两天由于测试需要,研究了一下 C# 操作 Excel,做了一个简单的总结,比如创
建 Excel,打开 Excel,关闭 Excel,读取指定的 sheet,读取指定的单元格等。
注意:对于命名空间 Microsoft.Office.Interop.Excel,使用之前需要引用 COM:
Microsoft Office 11.0 Object Library(office 2003 )或者 Microsoft Office 12.0 Object
Library(office 2007 )或者 Microsoft Office 14.0 Object Library(office 2010 )
using System.Reflection; // 引用这个才能使用 Missing 字段
2 基本类
2.1 ApplicationClass
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.applicati
onclass_members(v=office.11).aspx
2.2 WorkbookClass
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workboo
kclass_members(v=office.11).aspx
2.3 WorksheetClass
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workshe
etclass_members(v=office.11).aspx
3 接口
3.1 Workbook
Workbooks 包含了 Excel 中打开的所有 Workbook
ActiveWorkbook 是前端显示的 Workbook
ThisWorkbook 返回正在运行 add-in 的 Workbook
3.2 Worksheet
Worksheets 包含了所有包含在 Workbook 中的 Worksheet
ActiveSheet 是前端显示的 Worksheet
4 基本操作
4.1 新建 excel 文件
Application app=new Application();
Workbook wbook=app.Workbook.Add(Type.missing);
Worksheet worksheet=(Worksheet)wbook.Worksheets[1];
4.2 打开 Excel 文件
Application app=new Application();
Workbook
wbook=app.Workbooks.Open(excelfullpath,Type.Missing,Type.missin
g,Type.missing,Type.missing,Type.missing,Type.missing,Type.missin
g,Type.missing,Type.missing,Type.missing,Type.missing,Type.missin
g,Type.missing,Type.missing);
或
app.Workbooks.Open(Path,0,true,5,"","",true,Excel.XlPlatform.xlWindows,"\t",
false,false,0,true,1,0);
wbook =
4.3 保存 Excel 文件
worksheet.SaveAs
(excelfullpath ,Type.missing,Type.missing,Type.missing,Type.missing,Type.m
issing,Type.missing,Type.missing,Type.missing);
4.4 选择某个表格
Excel.Sheets sheets = workBook.Worksheets;
Excel.Worksheet workSheet =
(Excel.Worksheet)sheets.get_Item(sheet_name);
4.5 设置单元格内容
worksheet.Cells[rowIndex,colIndex]="单元内容"
4.6 读取单元格内容
string
str=((Range)worksheet.Cells[rowIndex,colIndex]).Value2.ToString();
string str=((Range)worksheet.Cells[rowIndex,colIndex]).Text;
http://zxfcool2000.blog.163.com/blog/static/31852320118
2351420572/(委托与事件)
4. C#委托和事件
委托+事件是观察者模式的一个典型例子,所谓的委托其实就是观察者,它会关心某种事件,一旦这种事
件被触发,这个观察者就会行动。
下面是最近写的一个例子,相信能够加深大家对委托和事件的理解。
using System
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication3
{
//定义一个委托,委托其实就是“方法模板”,就好像“类”是“对象”
的模板一样。如果某个类想在事件触发的时候收到通知,它必须有一个符合这种
格式的方法,在这个例子中,就是:返回类型为 void,参数类型为 object、
TimeEventArgs。
public delegate void TimeEventHandler(object obj, TimeEventArgs
args);
//TimeEventArgs 是我们自己定义的一个类,用于保存事件中的参数。
这里我们分别保存时间的时分秒。
public class TimeEventArgs:EventArgs
{
private int hour;
private int minute;
private int second;
public TimeEventArgs(int hour, int minute, int second)
{
this.hour = hour;
this.minute = minute;
this.second = second;
}
public int Hour
{
get
{
}
return hour;
}
public int Minute
{
get
{
return minute;
}
}
public int Second
{
get
{
}
}
}
return second;
//这是一个观察者类,它有一个符合我们上面定义的“委托”的方法,也就是
void ShowTime(object obj, TimeEventArgs args),从这个方法的定义可以看到,
我们只会关心返回类型和方法的参数,而方法名称则无所谓。
class MyTimeEventHandlerClass
{
}
public void ShowTime(object obj, TimeEventArgs args)
{
Console.WriteLine("现在时间是:"+args.Hour+":"+args.Minute+":"+args.Second);
}
//时钟类
class Clock
{
//我们在这个类中定义了一个“TimeChanged”事件,注意其
前面有两个关键字“event”和“TimeEventHandler”,其中 event 表示这是一
个事件,而不是方法或属性;TimeEventHandler 则指出,谁要监听 TimeChanged
事件,它就必须有一个符合 TimeEventHandler(委托)的方法。
public event TimeEventHandler TimeChanged;
public Clock()
{
//注意,这里的 null 的含义是指 TimeChanged 事件当
前还没有观察者关注它,如果某个观察者要关注 TimeChanged 事件,它必须要
让这个事件知道,方法是使用操作符“+=”来借助委托将其加载到事件上。
TimeChanged = null;
}
//时钟开始走动,我们的目标是每秒钟触发一次 TimeChanged
事件
public void go()
{
DateTime initi = DateTime.Now;
int h1 = initi.Hour;
int m1 = initi.Minute;
int s1 = initi.Second;
while (true)
{
DateTime now = DateTime.Now;
int h2 = now.Hour;
int m2 = now.Minute;
int s2 = now.Second;
if (s2!=s1)
{
h1 = h2;
m1 = m2;
s1 = s2;
存相关参数,这里是时分秒。
TimeEventArgs args = new TimeEventArgs(h2,m2, s2);
//首先建立一个 TimeEventArgs 对象来保
事件,事件不是类,所以不用使用“new”关键字,而且我们看到,这里
TimeChanged 的两个参数跟我们的委托(TimeEventHandler)是一致的,其中
第一个参数是触发这个事件的对象,我们这里使用的是一个时钟实例(this)。
//注意这种写法,这一句是用来触发
TimeChanged(this, args);
}
}
}
}
class Program
{
static void Main(string[] args)
{
Clock clock = new Clock(); //实例化一个时钟
//实例化一个观察者类
MyTimeEventHandlerClass tehc = new MyTimeEventHandlerClass();
//将事件跟我们定义的观察者进行连接,这样,clock 就会知道,每当
TimeChanged 事件被触发,就会去通知这个观察者,注意我们连接的时候使用
的并不是直接的观察者类实例中的 ShowTime()方法,而是一个委托,并在这个
委托中传递 ShowTime()方法,这也是“委托”的真正意义所在——我有一个方
法,但我委托你来帮我关联到事件,因为事件只会直接跟委托打交道,而不是观
察者的具体某个方法。
clock.TimeChanged+=new TimeEventHandler(tehc.ShowTime);