查看: 6485|回复: 9

Windows Forms系列之Windows Forms 单实例应用程序的创建

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2009-7-14 12:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1,利用VB的运行时库Microsoft.VisualBasic.dll包含的WindowsFormsApplicationBase类来实现这个功能

2,右键工程-添加引用-选择Microsoft.VisualBasic.dll项。然后添加新类Class1

3,编写代码(Class1.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualBasic.ApplicationServices;//注意

namespace WindowsFormsApplication1
{
    class Class1:WindowsFormsApplicationBase
    {
        public Class1()
        {
            this.IsSingleInstance = true;
        }
        static Class1 app;          //方便客户端程序的编写
        internal static Class1 App  //方便客户端程序的编写
        {
            get
            {
                if (app == null)
                {
                    app = new Class1();
                }
                return app;
            }
        }
        protected override void OnCreateMainForm()//重写主窗体创建函数
        {
            this.MainForm = new Form1();
        }
    }
}
4,改写Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string [] args)
        {
            Application.EnableVisualStyles();
            //Class1 app = new Class1();//不方便的写法
            //app.Run(args);            //不方便的写法
            Class1.App.Run(args);       //方便写法

            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
5,这样不管运行多少次,它都会限制应用程序只有一个实例。
论坛徽章:
0
2#
 楼主| 发表于 2009-7-14 12:54 | 只看该作者

C#播放Flash文件(SWF)

播放Flash动画的原理是引用Flash的dll.用它来播放.

先在工具箱中添加这个控件:

1.工具箱上点鼠标右键,出现菜单,选择 "Choose Items...",在出现的窗口选择"Com components"选项卡,

选择Shockwave Flash Object,打上勾,点"OK"按钮.

2.从toolbox中拖放一个flash控件到form中.

3.添加代码.

private void button3_Click(object sender, EventArgs e)
{
    axShockwaveFlash1.Movie = "D:\\duck01.swf";
    axShockwaveFlash1.Play();
}
注意,传给flash控件Movie属性时一定要传给完整的路径.

EmbedMovie: 是否嵌入到程序的资源中。 以上是swf文件的方法,flv格式的不行。

使用道具 举报

回复
论坛徽章:
0
3#
 楼主| 发表于 2009-7-14 12:54 | 只看该作者

Windows Forms 布局篇

1,控件的Z-Order顺序

垂直堆栈上的层次,可决定遮挡关系。调整方法:视图-其他窗口-文档大纲。

2,控件的Tab键顺序

按Tab键的切换顺序。调整方法:视图-Tab键顺序。

3,分隔控件

SplitContainer控件,可修改Orientation属性的值来改变垂直分隔还是水平分隔。在两个面板中可以设置FixedPanel属性来确定是否维持固定的大小。

4,分组

用分隔控件的时候往往需要将一组控件一起作为一部分,这时可以用GroupBox,Panel,TabPage这样的控件将若干控件进行分组。

使用道具 举报

回复
论坛徽章:
0
4#
 楼主| 发表于 2009-7-14 12:55 | 只看该作者

Windows Forms 对话框篇

1,标准对话框

Windows内置的对话框,又叫公用对话框,它们作为组件提供的,并且存在于System.Windows.Forms命名空间中。

手工方式:

private void button1_Click_1(object sender, EventArgs e)
{
    ColorDialog dlg = new ColorDialog();
    dlg.Color = Color.Red;
    DialogResult result = dlg.ShowDialog();
    if (result == DialogResult.OK)
    {
        MessageBox.Show("You picked " + dlg.Color.ToString());
    }
}
组件方式:

colorDialog1.Color = Color.Red;
DialogResult result = colorDialog1.ShowDialog();
if (result == DialogResult.OK)
{
    MessageBox.Show("You Picked " + this.colorDialog1.Color.ToString());
}
可见同样的功能,代码减少不少啊。

常用的标准对话框:

【ColorDialog】

颜色选取,返回值System.Drawing.Color类型的Color属性

【FolderBrowserDialog】

选择文件夹,返回值string类型的SelectdPath属性

【FontDialog】

选择字体,返回值System.Drawing.Font类型的Font

【OpenFileDialog】【SaveFileDialog】

打开或保存文件。返回string类型的FileName

【PageSetupDialog】【PrintDialog】【PrintPreviewDialog】

打印相关

2,窗体风格

相关属性:

ControlBox,FormBorderStyle.HelpButton,MaximizeBox,MinimizeBox,ShowIcon,ShowInTaskbar.

在运行中获取窗体时模式还是非模式:

if(this.Modal)

{

this.FormBorderStyle = FormBorderStyle.FixedDialog;

}

else

{

this.FormBorderStyle = FormBorderStyle.Sizable;

}

3,数据交换

可以直接操作:

Form2 dlg = new Form();

dlg.textBox1.Text = “My Name”;

DialogResult result = dlg.ShowDialog();

if(result==DialogResult.OK)

{

//Do Something

}

弊端如果Form2设计改动时(例如改变TextBox为LabelBox),需要改Form1的代码。

这样做比较好:在Form2中添加公共成员,给外部使用。

public string AppName {
    get { return this.textBox1; }
    set { this.aStr = value; }
}
调用时候:

Form2 dlg = new Form();

dlg.AppName = “My Name”;

DialogResult result = dlg.ShowDialog();

if(result==DialogResult.OK)

{

//Do Something

}

4,Dialog的返回,处理OK按钮和Cancel按钮

手工处理:

Form1:
private void button3_Click(object sender, EventArgs e)
{
    Form2 dlg = new Form2();
    dlg.Text = "Jor";
    DialogResult result = dlg.ShowDialog();
    if (result == DialogResult.OK)
    {
        MessageBox.Show(dlg.AppName);
    }

}
Form2:
private void button1_Click_1(object sender, EventArgs e)
{
    this.DialogResult = DialogResult.OK;//不用 Close()关闭了,一回事
}
如果窗体需要返回Cancel是一样的:

private void button1_Click_1(object sender, EventArgs e)
{
    this.DialogResult = DialogResult.Cancel;
}
手工方式的方式无法将按钮设置成默认按钮,默认按钮是按Enter键调用的那个按钮,按Esc键的时候,Cancel按钮应该被调用。实现这些很简单,只要配置窗体的AcceptButton和CancelButton就可以了。设置好之后发现Cancel按钮的DialogResult属性被自动设置成DialogResult.Cancel了,所以也没必要像手工方式一样去处理Cancel按钮的Click事件的处理程序了。OK也一样,设置好AccepuButton之后,OK按钮的默认值还是DialogResult.None,所以需要手工修改为DialogResult.OK

5,非模式窗体数据传递

与模式窗体的方式不同,需要用户自定义消息以及事件来完成数据交换的功能

在非模式窗体中自定义消息,以及事件触发的条件等。

代码:

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 WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        
        public event EventHandler Accept;//定义事件 ***自定义添加(与主窗体处理函数要对应)***

        private void button1_Click(object sender, EventArgs e)
        {
            if (Accept != null)
            {
                Accept(this, EventArgs.Empty);//按下按钮时触发事件***触发自定义事件***
            }
        }
        
    }
}
在主窗体中进行在非模式窗体中定义的事件与处理函数的绑定。当非模式窗体触发该事件时,由绑定的处理函数进行处理。

代码:

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 WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 frm = new Form2();
            frm.Accept += MyAccept;
            frm.Show();
        }
        void MyAccept(object sender, EventArgs e)
        {
            Form2 frm2 = (Form2)sender;
            this.label1.Text = frm2.textBox1.Text;//这里是直接调用,需要设置一下textBox1的公开特性。也可用代理方式,推荐。
        }
    }
}


注意:对于textBox1.Text的调用,默认情况下是不可以的,因为textBox1在Form1.Designer.cs中定义为private,可以改成public然后像这个例子中的方式进行调用。当然,最好用上面做代理的方式进行调用。

public string AppName { get { return this.textBox1; } set { this.aStr = value; } }

6,数据验证

可以添加Validating事件处理,Validating事件当焦点从一个CausesValidation属性为true的控件转移到另外一个CausesValidation属性为true的控件时发生。如果没有取消Validating事件,窗体会通过Validated事件得到通知。

代码:

private void textBox1_Validating(object sender, CancelEventArgs e)
{
    if (((Control)sender).Text.Trim().Length == 2)
    {
        MessageBox.Show("Please enter a name", "Error");
        e.Cancel = true;//是否可以切换焦点
    }
}


private void textBox1_Validated(object sender, EventArgs e)
{
    MessageBox.Show("My Name is ," + this.textBox1.Text, "Thanks");
}
为了允许用户在没有输入有效数据的情况下点击Cancel按钮来关闭窗体,我们必须将Cancel或Close按钮的CausesValidatin属性设置为true

         private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(190, 198);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.CausesValidation = false; //注意这里
              this.button1.Click += new System.EventHandler(this.button1_Click_1);
            //
            // textBox1
            //
       //...
      }

其他的可以用正则表达式或掩码文本的方式来进行数据验证

数据格式的通知功能(添加ErrorProvider组件):

private void textBox1_Validating(object sender, CancelEventArgs e)
{
    string error = null;
    if (((Control)sender).Text.Trim().Length == 0)
    {
        error = "Please enter a name";
        e.Cancel = true;//是否可以切换焦点
    }
    this.errorProvider1.SetError((Control)sender, error);
}

使用道具 举报

回复
论坛徽章:
0
5#
 楼主| 发表于 2009-7-14 12:55 | 只看该作者

Windows Forms 窗体篇

1,显示窗体

非模式:

Form form = new Form();

form.Show();

模式:

Form form = new Form();

form.Show();

2,拥有者窗体与附属窗体

模式:建立隐式的拥有着与附属关系

非模式:不建立隐式附属关系,但可以显式指定

OwnedForm form  = new OwnedForm();

form.Owner = this;

form.Show();

或者更简单的:

OwnedForm form  = new OwnedForm();

form.Show(this);

当然模式也可以显式指定,效果一样。

拥有者窗体可以遍历所有的附属者窗体:

foreach(Form ownedFor in this.OwnedForms)

{

    MessageBox.Show(ownedForm.Text);

}

对于非模式的窗体指定附属关系和不指定附属关系,窗体运行效果还是有些区别的:

显式指定附属关系的:附窗体在切回主窗体时仍然在上层,遮挡住下面的主窗体。

主窗体最小化的话,全部窗体都将最小化。

注意区别:Owner属性和Parent属性的区别,Parent属性(大多数为null),是用在MDI窗体上的。

3,窗体的生命周期:

在Show和ShowDialog之前,用户是看不见窗体的,但只要窗体被实例化了,那么这个窗体就存在了。

【窗体打开事件顺序】:

A,构造函数:

构造函数InitializeComponent();后面

Button btn  = mew Button();

this.controls.Add(btn);

this.Text = DateTime.Now.ToString();

B,LOAD事件:

Show,ShowDialog之前发生。此时窗体还没有被显示出来哦。

C,Activated事件:

窗体首次加载的时候,会成为激活窗体,也就是可以接受键盘输入的前台窗体。前通知。

D,Shown事件:

激活以后,窗体将被现实出来。前出事件。然后窗体将显示出来。



【窗体运行中事件】:

Deactivate事件:

当前窗体变成非活动窗体时发生。

Activated事件:

变成活动窗体时发生。

VisibleChanged事件:

当用this.Show()或this.Hide()。同 this.Visible = true 或 this.visible = false

【窗体关闭阶段】:

调用this.Close();关闭这个窗体

FormClosing事件:

在结束程序之前给用户提供一个机会来改变他们的操作。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    DialogResult result = MessageBox.Show("Abort your Form?", "Form In Progress", MessageBoxButtons.YesNo);
    e.Cancel = (result == DialogResult.No);
}
FormClosed事件:

提供了窗体已经消失的一个通知,虽然触发的时候窗体仍然可见。可以查询FormClosingEventArgs和FormClosingEventArgs提供的CloseReason属性来过的他:

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    MessageBox.Show("Your Form was aborted: " + e.CloseReason.ToString());
}
在FormClosed事件触发之后,如果没有取消窗体的关闭操作,窗体会在消失之前最后触发Deativated事件。

4,系统托盘通知(NotifyIcon控件)

例:程序点击最小化的时候隐藏,是很常见的功能,但是因为C#没有最小化的事件的处理,所以不能直接使用,在网上找了找,别人都是resize和其他几个事件处理,当然也可以在Deactivate事件实现,实现代码如下:

窗体的Deactivate事件,判断窗体状态是否为最小化,其他事件判断会出现问题:

private void MainForm_Deactivate(object sender, EventArgs e)  

{  


    if (this.WindowState == FormWindowState.Minimized)  

    {  

        this.ShowInTaskbar = false;  

        this.Hide();  

    }  

}

notifyIcon单击显示

private void notifyIcon1_Click(object sender, EventArgs e)

{

     
    this.Show();

     
    this.ShowInTaskbar = true;

    this.WindowState = FormWindowState.Normal;

    this.BringToFront();

}

控制NotifyIcon的现实,可以直接操作Visible属性。

【快捷菜单】

添加ContextMenuStrip组件,制作方法与制作雷同,完成后通过notifyIcon的contextMenuStrip属性进行关联。运行后右键托盘图标时,就会弹出快捷菜单。

【气泡提示条】

private void button_Click(object sender, EventArgs e)
{
    this.notifyIcon1.BalloonTipText = "我是气泡提示条哦!";
    this.notifyIcon1.ShowBalloonTip(3000);
}
运行结果:



5,其他窗体属性:

【FormBorderStyle】

窗体的样式,是否有边框,是否可以改变大小等。默认是:Sizable

【ControlBox】

布尔属性,是否在窗体左上角显示图标及右上角显示关闭按钮。

【MaximizeBox】【MinimizeBox】

最大化和最小化按钮是否显示在标题栏里。

【HelpButton】

问号按钮是否显示在标题栏里。上面为false时才有效。默认为false

【Icon】

窗体图标

【ShowIcon】

是否显示窗体图标

【SizeGripStyle】

来自于SizeGripStyle枚举类型的任何值:Auto,Hide或Show。右下角可移动时的样式。Auto是根据窗体FormBorderStyle的属性决定。不过窗体有状态条控件,那么此属性会被忽略,他会采用状态条控件上的SizingGrip属性来决定这一点。

【ShowInTaskbar】

布尔属性,决定窗体的Text是否显示在Windows的任务栏中。

6,透明窗体

Opacity 属性来设置透明度。

7,非矩形窗体

TransparencyKey设置的颜色与窗体BackColor相同的值,那么窗体将透明。

在窗体中绘制的图形,只要不是BackColor相同颜色,那么将被显示。为了效果更加理想,应该设置窗体FormorderStyle属性为None。

但在窗体上放置的PictureBox不受影响。

如果窗体FormorderStyle属性为None,那么移动起来就要自己处理了。

例如:

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;
    downPoint = new Point(e.X, e.Y);
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (downPoint == Point.Empty) return;
    Point location =
        new Point(
                this.Left + e.X - downPoint.X,
                this.Top+e.Y-downPoint.Y
            );
    this.Location = location;
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button != MouseButtons.Left) return;
    downPoint = Point.Empty;
}
这样点击窗体任何一个地方就可以实现移动的效果了。

8,窗体菜单与快捷菜单

菜单(MenuStrip):

窗体可以承载一个或多个菜单条,所有菜单条运行时都可见。通过设置MenuStrip的Visible属性可以隐藏或显示摸个菜单条控件。

主要属性:

【Checked】【checkOnClick】

某个菜单项是否已被选中,以及某个菜单项是否可以被选中。

【Enable】【Visible】
是否灰色,是否可见。

【Image】

菜单项的图像

【ShortCutKeys】

快捷键的设置

【Text】

显示文字,首字符加下划线用&来修饰

【TextAlign】【TextImageRelation】

没有图像或有图像时文本的对齐方式

快捷菜单(ContextMenuStrip):

设计方式与菜单控件类似,但与之不同的是,窗体和控件都有一个ContextMenuStrip属性,我们可以指定当点击鼠标右键是出现的快捷菜单,只有设置了这个属性后,右键单击控件弹出快捷菜才有效。

9,工具条(ToolStrip)

设计方法与菜单类似。主要属性如下:

【Image】【ImageAlign】

显示图像,对齐方式。

【Text】

显示的文本

【TextAlign】

文本的对齐方式

【TextImageRelation】

文本和图像之间的显示关系

【DisplayStyle】

是否显示文本或图像,或两者都显示。

【Checked】

开关风格的按钮的支持

【Enable】【Visible】

同菜单。

10,状体条(StatusStrip)

通过只能标签选项(控件上三角小箭头),来添加状态条的子组件。文本(可显示图片),进度条等。在文本组件中可以设置Spring属性来最大化的占用状态条的剩余空间。

主要属性如下:

【Image】【ImageAlign】

显示一副图像并将它对齐在可显示区域中。

【Text】

显示的文本

【DisplayStyle】

死否显示文本或图像,或两者都显示

【TextImageRelation】

文本和图像之间的显示关系

【IsLink】【LinkBehavior】

将指定的文本显示为超链接,并规定了工具条在鼠标操作时如何响应。

【Checked】

开关风格的按钮支持

【Enable】【Visible】

同前。

【Spring】

指定ToolStripStatusLabel是否最大化的填充

使用道具 举报

回复
论坛徽章:
0
6#
 楼主| 发表于 2009-7-14 12:57 | 只看该作者

Windows Forms 控件的布局

1,锚定功能(Anchor属性)

默认为“Top,Left”,不管窗体大小如果改变,保持相对于窗体左上角的位置。

如果设置为”Top,Bottom,Left,Right”这样,控件的大小将随窗体的大小改变,但距离窗体四边的距离不变。

2,停靠功能(Dock属性)

允许将控件粘在容器的边界上,默认为”None”(StatusStrip控件默认值为Bottom)。

典型应用:分割条切分窗体应用。

使用道具 举报

回复
论坛徽章:
0
7#
 楼主| 发表于 2009-7-14 12:58 | 只看该作者

Windows Forms 起步

1,新建窗体应用程序,在解决方案资源管理器中,双击Program.cs文件。



2,打开Program.cs文件如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
3,可以看出这里是应用程序的入口点,将Main函数中的语句屏蔽,由自己来创建窗体。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Form myForm = new Form();
            myForm.Show();

            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
4,这时创建的为非模式窗体,闪一下就没了,因为Main函数已经返回,可以用模式的窗体试试看。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Form myForm = new Form();
            myForm.ShowDialog();

            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
5,这时产生空白窗体,但Main函数阻塞,直到产生的窗体关闭。



6,为了让这个窗体在应用程序其余部分可以访问,我们将指定一个窗体作为主窗体。可以用System.Windows.Forms命名空间的Application对象的静态方法Run方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Form myForm = new Form();
            Application.Run(myForm);

            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
7,当然,还可以设置窗体的属性

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Form myForm = new Form();
            myForm.Text = "Hello World!";
            Application.Run(myForm);

            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
运行结果:



8,一般的,可以自定义窗体派生自Form类,在这个派生类中初始化自身的属性

添加新类:

Class1.cs 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class Class1:Form
    {
        public Class1()
        {
            this.Text = "Hello World";
        }
    }
}
Program.cs 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Form myForm = new Class1();
            Application.Run(myForm);

            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
        }
    }
}
运行结果同上例。

9,在窗体上添加一个按钮,并添加Click处理函数

Class1.cs 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class Class1:Form
    {
        public Class1()
        {
            this.Text = "Hello World";
            Button button = new Button();
            button.Text = "Click Me";
            button.Click += new EventHandler(button_Click);
            this.Controls.Add(button);
        }
        void button_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello World!");
        }
    }
}
运行结果:点击按钮,弹出 Hello World 字样的消息框。



以上代码订阅事件部分可以简单的方式。如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class Class1:Form
    {
        public Class1()
        {
            this.Text = "Hello World";
            Button button = new Button();
            button.Text = "Click Me";
            button.Click += button_Click;  //注意这里
            this.Controls.Add(button);
        }
        void button_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello World!");
        }
    }
}
到此为止,都是手工方式书写代码,一般的,这些工作大部分都可以由IDE辅助完成。

10,现在可以使用IDE来完成,点击顶端具有闪电图标的Event按钮来打开对应的事件列表。找到希望处理的事件(如Click),输入事件触发式希望调用的函数的名称(如button_Click函数),然后按Enter键(注:如果只想默认指定函数名称,则不用输入直接双击空白处即可产生)。这样IDE就帮我们生成了事件处理的框架,如下:

private void button_Click(object sender, EventArgs e)
{
}
这样就可以添加事件的处理了。如果添加第二个Button的时候,可以同样可以再Click下拉列表中找到上面的处理函数,这样,两个Button可以共享同一个事件处理函数,而不用重新定义了,通过sender参数,可以确定到底是哪个Button的触发的事件。例子代码:

private void button_Click(object sender, EventArgs e)
{
    Button button = sender as Button; //必要的类型转换
    MessageBox.Show(button.Text + " was clicked!");
}
【END】

使用道具 举报

回复
论坛徽章:
0
8#
 楼主| 发表于 2009-7-14 12:59 | 只看该作者

多线程与GUI

1,Windows窗体控件不是线程安全的,如果多个线程操控WindowGUI组件,结果可能不正确。为了保证线程以线程安全的方式操控GUI组件,与GUI组件的所有交互都要由用户界面线程(UI线程)来执行,即创建和维护GUI的线程。Control类提供Invoke方法可以帮助这个过程。

2,Form1设计窗体:



3,Form1.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;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private Class1 letter1;
        private Class1 letter2;
        private Class1 letter3;

        private void Form1_Load(object sender, EventArgs e)
        {
            letter1 = new Class1(label1);
            Thread firstThread = new Thread(new ThreadStart(letter1.GenerateRandomCharacters));
            firstThread.Name = "Thread 1";
            firstThread.Start();

            letter2 = new Class1(label2);
            Thread secondThread = new Thread(new ThreadStart(letter2.GenerateRandomCharacters));
            secondThread.Name = "Thread 2";
            secondThread.Start();

            letter3 = new Class1(label3);
            Thread thirdThread = new Thread(new ThreadStart(letter3.GenerateRandomCharacters));
            thirdThread.Name = "Thread 3";
            thirdThread.Start();

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Environment.Exit(System.Environment.ExitCode);
        }

        private void threadCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (sender == checkBox1)
                letter1.Toggle();
            else if (sender == checkBox2)
                letter2.Toggle();
            else if (sender == checkBox3)
                letter3.Toggle();
        }

    }
}
3,Class1.cs 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;

namespace WindowsFormsApplication1
{
    class Class1
    {
        private static Random generator = new Random();
        private bool suspended = false;
        private Label output;
        private string threadName;

        public Class1(Label label)
        {
            output = label;
        }

        private delegate void DisplayDelegate(char displayChar);

        private void DisplayCharacter(char displayChar)
        {
            output.Text = threadName + ":" + displayChar;
        }

        public void GenerateRandomCharacters()
        {
            threadName = Thread.CurrentThread.Name;
            while (true)
            {
                Thread.Sleep(generator.Next(1001));
                lock (this)
                {
                    while (suspended)
                    {
                        Monitor.Wait(this);
                    }
                }
                char displayChar = (char)(generator.Next(26) + 65);
                output.Invoke(new DisplayDelegate(DisplayCharacter), new object[] { displayChar });
            }
        }
        public void Toggle()
        {
            suspended = !suspended;
            output.BackColor = suspended ? Color.Red : Color.LightGreen;
            lock (this)
            {
                if (!suspended)
                {
                    Monitor.Pulse(this);
                }
            }
        }
    }
}
4,运行结果:可以看到3个线程分别更新Label的随机字母,点ComboBox随时暂停。



[END]

0 0
(请您对文章做出评价)

使用道具 举报

回复
论坛徽章:
0
9#
 楼主| 发表于 2009-7-14 12:59 | 只看该作者

C# GUI 设计初步(一)

1,控件的常用属性

控件从Control类(System.Windows.Forms 名字空间)派生。下表列出Control类的常用属性及方法。

常见属性:

BackColor 背景色

BackgroundImage 背景图形

Enable 是否可用(变灰)

Focused 是否获得焦点

Font 文本字体

ForeColor 前景色(Test属性中文本的颜色)

TabIndex 控件跳表顺序(按Tab的时候切换焦点的顺序)

TabStop 是否可以将焦点停留此控件

Test 控件相关文本

Visable 控件是否可见

常见方法:

Focus 使之获得焦点

Hide 隐藏控件

Show 显示控件(与 Hide 方法对应)



2,控件的布局属性

Anchor 使控件与容器边缘保持固定距离,即使容器缩放

Dock 使控件占满容器一边或整个容器

Padding 设置容器边与控件的间距。默认为0,使控件与容器边缘对齐

Location 控件左上角相对于容器的坐标

Size 控件大小,具有Width与Height属性

MinimumSize,MaximumSize 控件的最大最小尺寸,用户拖拉窗体边缘时的范围限定值,如两者相同则不能拖拉



3,Lable(卷标)控件的常用属性

TextAlign 卷标文本与控件的对齐方式



4,TextBox(文本框)控件的常用属性与事件

常见属性:

AcceptsReturn 如果True,则多行文本框中按Enter键时另起新行。如果False,则和其他的默认按钮一样。默认按钮是AcceptButton按钮指定的按钮

Multiline 是否是多行文本

PasswordChar 密码输入时显示的字符

ReadOnly 是否只读

ScrollBars 滚动条样式

常见事件:

TextChanged 在文本框中文本改变时促发



5,Button(按钮)控件的属性与事件

常见属性:

FlatStyle 按钮外观样式

常见事件:

Click 单击按钮时产生



6,CheckBox(复选框)控件的属性与事件

常见属性:

Checked 复选框是否选择

CheckState 复选框状态3种(Checked,Unchecked,Indeterminate),Indeterminate表示不确定状态,显示阴影

常见事件:

CheckChanged 在改变Checked属性时产生

CheckStateChanged 改变CheckState属性时产生



7,RadioButton(单选按钮)控件的属性与事件

Checked 是否选择

常见事件:

CheckChanged 在改变Checked属性时产生

注意:RadioButton在相同容器中为一组,只可单选。但在不同容器中不受影响

使用道具 举报

回复
论坛徽章:
36
生肖徽章:兔
日期:2007-06-22 14:08:212012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:252012新春纪念徽章
日期:2012-02-13 15:12:25版主2段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-10-09 18:09:192013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:43:09马上有钱
日期:2014-02-18 16:43:09马上有车
日期:2014-02-19 11:55:14
10#
发表于 2009-7-15 18:40 | 只看该作者
up!,hao wen

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表