binzhouweichao@163.com
2013-10-17
仍然沿用前面所使用的项目。
参考:
访问控件私有属性:http://bbs.csdn.net/topics/40412507
静态类与非静态类:http://www.360doc.com/content/13/0608/09/10504424_291426603.shtml
1. 在主窗体类中自定义显示、隐藏图片函数
在主窗体的TriPaint类中自定义这两个函数,使得每个控件的事件函数可以直接调用此函数。
在TriPaint类的构造函数后面添加:
//自定义显示图片函数
public void showImage()
{
pictureBox1.Image = GlobalVars.B;//显示图像b
pictureBox1.Refresh();//刷新图片框
}
//自定义隐藏图片函数
public void hideImage()
{
pictureBox1.Image = null;//图片置空
pictureBox1.Refresh();//刷新图片框
}
然后把每个控件事件中的显示隐藏图片的代码用上述两个函数代替。
修改后的TriPaint.cs代码为:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TriPaint_20131013
{
public partial class TriPaint : Form
{
public TriPaint()
{
InitializeComponent();
//在这里添加代码
//对数据进行处理
for (int i = 0; i < GlobalVars.POINTCNT; i++)
{
GlobalVars.Data[i].X = (int)(i * GlobalVars.xInterval);//i对应的data.X
GlobalVars.Data[i].Y = (int)(GlobalVars.times * Math.Sin(GlobalVars.Data[i].X / GlobalVars.times));//sin函数求值
GlobalVars.Data[i].Y = (int)(GlobalVars.Data[i].Y + GlobalVars.times * 1);//Y轴向正向平移1,即1*times,令最高点(也就是3π/2对应的-1点)的值为0
}
}
private void TriPaint_Load(object sender, EventArgs e)
{
//Graphics g = this.CreateGraphics();//画板
//this.Show();//显示
//Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);//新建图像画布
Graphics g = Graphics.FromImage(GlobalVars.B);//图像画布添加绘图
//坐标系平移镜像
g.TranslateTransform(0, 250);//向y正向平移250
g.ScaleTransform(1, -1);//关于x轴镜像
Pen p = new Pen(Color.Blue, 1);//画笔
g.DrawLines(p, GlobalVars.Data);//多点绘图,直线连接
//pictureBox1.Image = b;//图像框的图像为上述绘图生成的图像
//释放绘图所占用资源
p.Dispose();
g.Dispose();
//b.Dispose();
}
//自定义显示图片函数
public void showImage()
{
pictureBox1.Image = GlobalVars.B;//显示图像b
pictureBox1.Refresh();//刷新图片框
}
//自定义隐藏图片函数
public void hideImage()
{
pictureBox1.Image = null;//图片置空
pictureBox1.Refresh();//刷新图片框
}
private void button1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
showImage();//显示图片
}
private void button2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
hideImage();//隐藏图片
}
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
showImage();//显示图片
}
private void hideToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
hideImage();//隐藏图片
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
showImage();//显示图片
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
hideImage();//隐藏图片
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (pictureBox1.Image == null)//如果图像为空
{
toolStripStatusLabel1.Text = "Hide";//则显示Hide
}
else//否则,即图像不为空,有具体的BMP位图
{
toolStripStatusLabel1.Text = "Show";//则显示Show
}
}
}
}
结果图不变。
2. 开放控件的部分私有属性,供外部类的函数访问
公开控件部分私有属性,在其类TriPaint中进行。
公开的变量有两种类型:静态static变量和非静态变量。
静态变量在程序初始化时就已经分配好内存,其变量的地址不变,区别于const常量,其变量的值可以变。
非静态变量与之相反,在程序运行后才会分配内存,如果是局部变量,当前域运行结束后,收回内存,销毁变量。
这里还要说一下静态类static class 和非静态类。
C#中,静态类不能实例化对象。也就是说,静态类中的成员变量,可以直接使用类名的方式引用,而不需要使用具体的对象实例来引用。
非静态类与之相反。若想要在外部引用非静态类的成员变量,需要将此类实例化,通过对象实例的方式来引用。
下面通过具体的例子来说明。仍然使用前面的项目。
2.1 对开放的属性仅作读取get,不作重新赋值set
比如pictureBox1的Width和Height属性,在GlobalVars中,仅使用这两个属性对位图b的大小进行初始化。
在非静态类TriPaint中,设置公共非静态变量PicW和PicH来公开这两个私有属性
这种方法,只是用于属性不变的情况,即pictureBox1的Width和Height在设计时设置好Size属性后,后面所有的调用都不会更改这个属性,程序中只会读取这个属性的值,不会再对其作修改。对于同一个主窗体类TriPaint,如果实例化不同的对象,pictureBox1的W和H属性是相同的。
这样,在TriPaint类的构造函数后面,可以添加上公开图片框宽高属性的代码:
//公开pictureBox1的Width和Height属性,仅供读取
public int PicW
{
get { return pictureBox1.Width; }
}
public int PicH
{
get { return pictureBox1.Height; }
}
在GlobalVars类中,就可以读取到这两个属性,从而得到位图b的大小。
这里要注意,引用非静态类的成员,需要将类实例化,通过引用类的实例对象的方式来引用其成员。类TriPaint为非静态类,所以,在GlobalVars中,引用其成员PicW和PicH时,需要通过建立实例对象的方式引用。
有两种引用的方式:
一种是声明类的实例对象,可以不设置对象名,直接通过new来实现。
在GlobalVars中,创建位图b时的代码为:
//位图b,为pictureBox1.Image使用的值
//private static Bitmap b = new Bitmap(250, 250);
private static Bitmap b = new Bitmap(new TriPaint().PicW, new TriPaint().PicH);
这里的原理,就如上面所说,对于TriPaint类声明的不同的实例对象,其pictureBox1的宽高属性是相同的。
第二种是,声明一个TriPaint类的静态对象实例,并初始化,然后下面通过实例名来引用。
//位图b,为pictureBox1.Image使用的值
//private static Bitmap b = new Bitmap(250, 250);
//private static Bitmap b = new Bitmap(new TriPaint().PicW, new TriPaint().PicH);
//创建类的静态实例triPaint
private static TriPaint tripaint = new TriPaint();
public static TriPaint triPaint
{
get { return tripaint; }
set { tripaint = value; }
}
private static Bitmap b = new Bitmap(triPaint.PicW, triPaint.PicH);
这种方法的好处是,引用的PicW和PicH是同一个实例的,不必担心不同实例的同一属性是否相同。
打开项目的Program.cs文件,可以看到,在程序入口main函数中,运行程序时,创建了一个TriPaint类的对象,只不过未命名而已。这样,我们可以将其改为GlobalVars中声明的TriPaint类实例triPaint,就可以统一对象了。代码如下:
//Application.Run(new TriPaint());
Application.Run(GlobalVars.triPaint);//使用全局变量中声明的TriPaint类的实例对象,以统一实例
2.2 对公开的属性既读取get,又赋值set
在本程序中,我们以状态栏的显示文本为例。虽然这样多次一举。。
在TriPaint的pictureBox1_Paint()事件函数中,对状态栏文本的切换,我们不使用本类内的toolStripStatusLabel.Text,而是将这个属性开放读写(get, set),在GlobalVars中建立一个外部全局变量,命名为StatusText,通过这个全局变量,实现状态栏文本的切换,达到读写该控件文本属性的目的。
在TriPaint类中,开放状态栏的标签的文本属性toolStripStatusLabel1.Text为读写:
//公开statusLabel的Text属性,供读写
public string StatusText
{
get { return toolStripStatusLabel1.Text; }
set { toolStripStatusLabel1.Text = value; }
}
在GlobalVars类中,建立一个全局变量的StatusText,通过上面建立的triPaint实例,进行数据读写的传递:
//创建StatusText全局变量,通过实例triPaint进行传递
public static string StatusText
{
get { return triPaint.StatusText; }
set { triPaint.StatusText = value; }
}
这样,在TriPaint类中的更改状态栏显示文本的地方,将原先的类内控件属性的赋值方式改为全局变量GlobalVars.StatusText赋值方式:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (pictureBox1.Image == null)//如果图像为空
{
//toolStripStatusLabel1.Text = "Hide";//则显示Hide
GlobalVars.StatusText = "Hide";
}
else//否则,即图像不为空,有具体的BMP位图
{
//toolStripStatusLabel1.Text = "Show";//则显示Show
GlobalVars.StatusText = "Show";
}
}
注:这一部分绕来绕去说了这么多,只是为了演示外部类访问窗体类的控件的私有属性,包括读写。
3. 主窗体类外创建自定义函数来显示、隐藏图片
给项目添加一个新类,静态,命名为MyFunctions,用以创建自定义函数。
在新添加的MyFunctions.cs的类中,创建两个静态成员方法(函数),分别用于显示和隐藏图片,命名为ImageShow()和ImageHide()。
这两个函数功能与TriPaint类中自定义的那两个显示隐藏图片的函数相同,所以用到了pictureBox1的Image属性和Refresh()方法。
首先,在类TriPaint中将Image属性设为公有:
//公开pictureBox1的Image属性,供读写
public Image PicImage
{
get { return pictureBox1.Image; }
set { pictureBox1.Image = value; }
}
其次,在类TriPaint中将pictureBox1的私有方法Refresh()公开,命名为PicRefresh():
//公开pictureBox1的私有方法Refresh()
public void PicRefresh()
{
pictureBox1.Refresh();
}
在MyFunctions.cs的类MyFunctions中,创建两个函数,用来显示和隐藏图片。
为了调用方便,我们仍旧将MyFunctions定义为静态类,这样,其内部成员方法也必须定义为静态方法,从而可以直接使用类名进行引用,而不必将类MyFunctions实例化:
static class MyFunctions//静态类,使用类名直接进行引用
{
//显示图片
public static void ShowImage()//静态类中必须为静态成员方法
{
GlobalVars.triPaint.PicImage = GlobalVars.B;
GlobalVars.triPaint.PicRefresh();
}
//隐藏图片
public static void HideImage()
{
GlobalVars.triPaint.PicImage = null;
GlobalVars.triPaint.PicRefresh();
}
}
在TriPaint类中,将各事件函数的显示隐藏图片的地方更改为MyFunctions.ShowImage()和MyFunctions.HideImage():
private void button1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void button2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void hideToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
这样,修改完成后的各文件终稿为:
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace TriPaint_20131013
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new TriPaint());
Application.Run(GlobalVars.triPaint);//使用全局变量中声明的TriPaint类的实例对象,以统一实例
}
}
}
TriPaint.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TriPaint_20131013
{
public partial class TriPaint : Form
{
public TriPaint()
{
InitializeComponent();
//在这里添加代码
//对数据进行处理
for (int i = 0; i < GlobalVars.POINTCNT; i++)
{
GlobalVars.Data[i].X = (int)(i * GlobalVars.xInterval);//i对应的data.X
GlobalVars.Data[i].Y = (int)(GlobalVars.times * Math.Sin(GlobalVars.Data[i].X / GlobalVars.times));//sin函数求值
GlobalVars.Data[i].Y = (int)(GlobalVars.Data[i].Y + GlobalVars.times * 1);//Y轴向正向平移1,即1*times,令最高点(也就是3π/2对应的-1点)的值为0
}
}
//公开pictureBox1的Width和Height属性,仅供读取
public int PicW
{
get { return pictureBox1.Width; }
}
public int PicH
{
get { return pictureBox1.Height; }
}
//公开statusLabel的Text属性,供读写
public string StatusText
{
get { return toolStripStatusLabel1.Text; }
set { toolStripStatusLabel1.Text = value; }
}
//公开pictureBox1的Image属性,供读写
public Image PicImage
{
get { return pictureBox1.Image; }
set { pictureBox1.Image = value; }
}
//公开pictureBox1的私有方法Refresh()
public void PicRefresh()
{
pictureBox1.Refresh();
}
private void TriPaint_Load(object sender, EventArgs e)
{
//Graphics g = this.CreateGraphics();//画板
//this.Show();//显示
//Bitmap b = new Bitmap(pictureBox1.Width, pictureBox1.Height);//新建图像画布
Graphics g = Graphics.FromImage(GlobalVars.B);//图像画布添加绘图
//坐标系平移镜像
g.TranslateTransform(0, 250);//向y正向平移300
g.ScaleTransform(1, -1);//关于x轴镜像
Pen p = new Pen(Color.Blue, 1);//画笔
g.DrawLines(p, GlobalVars.Data);//多点绘图,直线连接
//pictureBox1.Image = b;//图像框的图像为上述绘图生成的图像
//释放绘图所占用资源
p.Dispose();
g.Dispose();
//b.Dispose();
}
//自定义显示图片函数
public void showImage()
{
pictureBox1.Image = GlobalVars.B;//显示图像b
pictureBox1.Refresh();//刷新图片框
}
//自定义隐藏图片函数
public void hideImage()
{
pictureBox1.Image = null;//图片置空
pictureBox1.Refresh();//刷新图片框
}
private void button1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void button2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
private void showToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void hideToolStripMenuItem_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
//pictureBox1.Image = GlobalVars.B;//显示图像b
//pictureBox1.Refresh();//刷新图片框
//showImage();//显示图片
MyFunctions.ShowImage();
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
//pictureBox1.Image = null;//对Image的值置空,刷新后图像就消失了
//pictureBox1.Refresh();
//hideImage();//隐藏图片
MyFunctions.HideImage();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (pictureBox1.Image == null)//如果图像为空
{
//toolStripStatusLabel1.Text = "Hide";//则显示Hide
GlobalVars.StatusText = "Hide";
}
else//否则,即图像不为空,有具体的BMP位图
{
//toolStripStatusLabel1.Text = "Show";//则显示Show
GlobalVars.StatusText = "Show";
}
}
}
}
GlobalVars.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace TriPaint_20131013
{
//修改这里
static class GlobalVars
{
//类似于#define宏定义,设置三个常量
public const int POINTCNT = 50;//点数,POINTCNT <= XMAX - XMIN
public const int XMAX = 200;//X轴最大值,也就是2π对应的值
public const int XMIN = 0;//X轴最小值
public const double times = (XMAX - XMIN) / (2 * Math.PI - 0);//放大倍数
public const double xInterval = (XMAX - XMIN) / (POINTCNT - 1);//i增量对应的data.X增量
//类似于全局变量,可以重新赋值
//坐标点变量
private static Point[] data = new Point[POINTCNT];
public static Point[] Data
{
get { return data; }
set { data = value; }
}
//位图b,为pictureBox1.Image使用的值
//private static Bitmap b = new Bitmap(250, 250);
//private static Bitmap b = new Bitmap(new TriPaint().PicW, new TriPaint().PicH);
//创建类的静态实例
private static TriPaint tripaint = new TriPaint();
public static TriPaint triPaint
{
get { return tripaint; }
set { tripaint = value; }
}
private static Bitmap b = new Bitmap(triPaint.PicW, triPaint.PicH);
public static Bitmap B
{
get { return b; }
set { b = value; }
}
//创建StatusText全局变量,通过实例triPaint进行传递
public static string StatusText
{
get { return triPaint.StatusText; }
set { triPaint.StatusText = value; }
}
}
}
MyFunctions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TriPaint_20131013
{
static class MyFunctions//静态类,使用类名直接进行引用
{
//显示图片
public static void ShowImage()//静态类中必须为静态成员方法
{
GlobalVars.triPaint.PicImage = GlobalVars.B;
GlobalVars.triPaint.PicRefresh();
}
//隐藏图片
public static void HideImage()
{
GlobalVars.triPaint.PicImage = null;
GlobalVars.triPaint.PicRefresh();
}
}
}
结果图不变。
项目代码: