本章简言

上一章笔者介绍了关于WinForm环境。这一章笔者将继续讲WinForm。只不过更加的面向开发了。事实就是在学习工具箱里面的控件。对于WinForm开发来讲,企业对他的要求并没有那么高。但是如果是游戏相关的话,不好意思!笔者觉得你可能选错语言了。C++可能更合适你。有一点希望读者们明白。下列讲到的内容是笔者在开发用的。只能辅助你学习,却不能成为教材。上一章讲到WinForm开发就是JAVA的Awt和Swing编程。笔者在做Awt和Swing已经过去四年多了。如果记得没有错的话,在设计窗体的时候笔者常常会用到关于FlowLayout类,BorderLayout类,JPanel类等布局类。所以先让我们看一下关于WinForm的布局吧。

WinForm布局

说到布局,笔者只能先从属性窗体切入了。记得大部分的控件都是从Control类这里继承过来的。而Control类中有俩个属性跟布局有一定有关系。一个是Anchor属性,一个是Dock属性。

Anchor属性的作用就是把控件绑定到其容器的边缘并确定控件随其容器一起调整大小。但是是按什么样的比列调整笔者也不是很清楚。MSDN也没有找到相关的说法。只是说明控件随其容器一起调整大小。下面就是Anchor属性的值。

    public enum AnchorStyles
{
// 摘要:
// 该控件未锚定到其容器的任何边缘。
None = 0,
//
// 摘要:
// 该控件锚定到其容器的上边缘。
Top = 1,
//
// 摘要:
// 该控件锚定到其容器的下边缘。
Bottom = 2,
//
// 摘要:
// 该控件锚定到其容器的左边缘。
Left = 4,
//
// 摘要:
// 该控件锚定到其容器的右边缘。
Right = 8,
}

如果你设置Right的话,当你把容器往右边拉的话,设置的控件大小也往右边变。还是让笔者举一个例子吧。

从图上可以看出笔者设置了四个值——上下左右。现在笔者就拖动一下看看他们的变化吧。

   

按扭是放在一个Panel类的容器里面的。现在笔者拖动了Panel就是发现按扭跟着一起发现变化。

Dock属性这个可以说是跟JAVA的BorderLayout类是一个样子的。把容器分为上、下、左、右、中五大区。所以对应的Dock属性的值也有五种。

 1     public enum DockStyle
2 {
3 // 摘要:
4 // 该控件未停靠。
5 None = 0,
6 //
7 // 摘要:
8 // 该控件的上边缘停靠在其包含控件的顶端。
9 Top = 1,
10 //
11 // 摘要:
12 // 该控件的下边缘停靠在其包含控件的底部。
13 Bottom = 2,
14 //
15 // 摘要:
16 // 该控件的左边缘停靠在其包含控件的左边缘。
17 Left = 3,
18 //
19 // 摘要:
20 // 该控件的右边缘停靠在其包含控件的右边缘。
21 Right = 4,
22 //
23 // 摘要:
24 // 控件的各个边缘分别停靠在其包含控件的各个边缘,并且适当调整大小。
25 Fill = 5,
26 }

你们可以自己动手试一下。就是设置对应的值。就是可以零距离停靠所设置的区。算了。笔者设置一下TOP吧。看一下样子吧。

上面俩个属性的功能大概多了解了。接下就来讲一下关于FlowLayoutPanel控件吧。JAVA的FlowLayout有一点类似。意为流动布局。而C#的这个叫流式布局面板。是一个容器。看一下下面的图片吧。

我们可以看到,如果不够位置放一个按扭的时候,会自动换行存放。FlowLayoutPanel控件里面有一个叫FlowDirection属性来设置流动的方向。是从左到右,是从上到下。这个吗读者们自行查看。

用户定义控件

在开发过程中,我们会发现官方提供的控件有时候并不能满足我们自己的业务需求。这个时候怎么办呢?其实开发人员完全可以自己组装一个控件。即是用户定义控件。选中项目右击》添加》用户控件。

填写对应的用户控件的名称之后,点击添加按扭。visual studio就会切换到用户控件的设计窗体界面,同时项目里面会多出一个文件。如下

上面的项目结构的图片了吧。我们可以看到多出一个叫ATextBox.cs的文件。文件前面的图标跟窗体的图标一点也不一样子。可是你却会发现操作却跟窗体操作是一样子。没有错。你可以把这个界面当作对窗体的操作就可以了。相信笔者不用多说了。该拖控件就拖吧。

如果你用心的话,可以点开他。这个时候你会发现真的有一点像呢?

笔者拖一个TextBox到ATextBox.cs里面吧。然后在拖动改变一下ATextBox.cs的大小吧。如图下。

好了。就这样子吧。那么要什么用呢?双击Form1.cs窗体。这个时候我们会发现对应的工具箱里面会出现一些细微的变化。

看到这里。不用笔者多说拉到对应的窗体就可以了使用了。这里要注意一点:如果你的用户控件发生了代码上的修改。就必须重新生成。这个时候拉出来才有可能是最新的。为了区别笔者把ATextBox.cs的背影色改为红色。让我们看一下吧。

让我们切到后面的代码吧。笔者在代码里面加了一个叫AText的属性。如下

 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9
10 namespace WinFormExample
11 {
12 public partial class ATextBox : UserControl
13 {
14 public ATextBox()
15 {
16 InitializeComponent();
17 }
18 public string AText
19 {
20 set { this.textBox1.Text = value; }
21 get { return this.textBox1.Text; }
22 }
23 }
24 }

这个时候我们来看一下。对应他的属性窗体里面就会出现相应的属性了。这个样子就可以修改他的值了。

相信读者们能明白笔者要表达的是什么意思了吧。没有错。如果你写了相关的事件。也会在他的属性窗体里面出现。那么有时候如果不想让他出现在属性窗体里面怎么办呢?这个时候我们就要看一个类了。UserControl类就是最好的学习了。按F12相看UserControl类。我们会发现一些注解。如Browsable、EditorBrowsable等。没有错。这些都是用于表示对应属性在属性窗体的行为。笔者就不用多说了吧。

[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[EditorBrowsable(EditorBrowsableState.Always)]
public override bool AutoSize { get; set; }

关于用户控件笔者就写到这里。这部分的内容笔者在开发过程中也很少用到。但是如果是大型PC端的软件开发。那一般都会用到。请读者们自己查阅。

应用程序配置文件

应用程序配置文件就是App.config。这是.NET自己创造一个以.config为扩展名的配置文件(事实上就是一个XML)。所以在读取上可以不用XmlDocument类。当然你要是觉得不爽也可以用XmlDocument了。这并没有多大影响。但是为了专业精神有时候笔者还是会用C#的读取方式。那App.config是什么呢?在开发WinForm一般都会用到他。你可以把对应的数据库连接字符串放在App.config。也可以存放一些其他的信息。没有错。就是用于存放应用程序的配置信息。那么C#自己提了一个叫ConfigurationManager类。这个类就是用于读取App.config。不多说让笔者举例子吧。

ConfigurationManager类是在System.Configuration的dll里面的。如果项目的引用里面没用的话。不好意思。请先引了一下。关于这一点相信《Java进击C#——项目开发环境》足够让你了解到。然后,就可以创建一个App.config了。选项目右击》添加》新建项。这个相信大家都明白了吧。

在常规里面就可以找到对应的“应用程序配置文件”了。选择“添加”。项目里面就会出现App.config.内容如下。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>

好了。我们要做的就是在App.config里面增加相关的信息了。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Aomi" value="i am aomi"/>
</appSettings>
</configuration>

这个时候笔者就要去读取相关的信息了。笔者在窗体里面拖了一个Label控件和一个按扭控件。点击按扭就把配置信息的值读取出来。赋值给Label控件。

后面代码

 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Configuration;
10
11 namespace WinFormExample
12 {
13 public partial class Form1 : Form
14 {
15 public Form1()
16 {
17 InitializeComponent();
18 }
19
20 private void button1_Click(object sender, EventArgs e)
21 {
22 this.label1.Text = ConfigurationManager.AppSettings["Aomi"];
23 }
24 }
25 }

看到代码了吧。就一句很简单的话就可以了。让我们看一下运行的情况吧。

关于App.config不只是笔者讲的这些。还可以用于设置开发软件的一些系统设置。这可就多了。是写不完的。请笔者们自行查阅。

BackgroundWorker类

这个类你可以理解为后台线程。在开发过程中,程序有很多不需用户看到的工作。这些工作一般都可以交给后面线程去工作。而BackgroundWorker类就是最好的代表了。对于BackgroundWorker类本来笔者应该在多线程那章节一起讲的。可是笔者想一下觉得放在这里比较合适。WinForm的界面执行都是在一个叫UI线程里面做的。那么UI线程有一个特色就是后台线程是访问不了UI线程里面的控件。一般的访都要用到一个叫Invoke方法。他是在Control类里面的。所以不管是控件还是窗体都有这个方法。看一下下面的代码吧。

 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Configuration;
10 using System.Threading;
11
12 namespace WinFormExample
13 {
14 public partial class Form1 : Form
15 {
16 public Form1()
17 {
18 InitializeComponent();
19 }
20
21 private void button1_Click(object sender, EventArgs e)
22 {
23 this.label1.Text = ConfigurationManager.AppSettings["Aomi"];
24 }
25
26 private void Form1_Load(object sender, EventArgs e)
27 {
28 Thread myThread = new Thread(this.Trace);
29 myThread.Start();
30 }
31
32 public void Trace()
33 {
34 this.Invoke(new Action(() =>
35 {
36 this.label1.Text = "这是一个 Trace";
37 }));
38 }
39 }
40 }

如果把它去掉的话,就会发生异常。如下

笔者举一个列子来说明一下BackgroundWorker类的用法吧。

 1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using System.Configuration;
10 using System.Threading;
11
12 namespace WinFormExample
13 {
14 public partial class Form1 : Form
15 {
16 private BackgroundWorker _backgroudWorker;
17 public Form1()
18 {
19 InitializeComponent();
20 }
21
22 private void button1_Click(object sender, EventArgs e)
23 {
24 if (this._backgroudWorker == null)
25 {
26 this._backgroudWorker = new BackgroundWorker();
27 this._backgroudWorker.WorkerSupportsCancellation = true;
28 this._backgroudWorker.WorkerReportsProgress = true;
29 this._backgroudWorker.DoWork += BackgroudWorker_DoWork;
30 this._backgroudWorker.ProgressChanged += BackgroudWorker_ProgressChanged;
31 this._backgroudWorker.RunWorkerCompleted += BackgroudWorker_RunWorkerCompleted;
32 }
33
34 this._backgroudWorker.RunWorkerAsync();
35
36 }
37
38 private void BackgroudWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
39 {
40 this.progressBar1.Value = e.ProgressPercentage;
41 }
42
43 private void BackgroudWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
44 {
45 this.label1.Text = e.Result.ToString();
46 }
47
48 private void BackgroudWorker_DoWork(object sender, DoWorkEventArgs e)
49 {
50 string value = ConfigurationManager.AppSettings["Aomi"];
51 e.Result = value;
52
53 for (int i = 0; i < 100; i++)
54 {
55 this._backgroudWorker.ReportProgress(i);
56 Thread.Sleep(200);
57 }
58
59 }
60
61 }
62 }

运行结果

BackgroundWorker类把后台和前台分开。并且又可以在后台执行过程中通知前台。我们可以看到BackgroundWorker类还是很强大的。同时也可以不用Invoke方法。

WorkerSupportsCancellation属性:用于表示是否可以在运行中取消工作。

WorkerReportsProgress属性:用于表示是否可以在运行中通知前台。

DoWork事件:后台线程

ProgressChanged事件:前台UI线程。用于后台线程中通知的时候执行。

RunWorkerCompleted事件:前台UI线程。用于后台线程结束之后执行。

RunWorkerAsync方法:开始异步运行。

本章总结

本章主要是讲到关于笔者在开发过程中用到的几个知识点。也是笔者认为学习WinForm必须要懂得。关于WinForm笔者就简单的介绍到这里。下一章我们要去看一下关于Linq和EF的知识点。

应用开发之WinForm开发的更多相关文章

  1. Java进击C#——应用开发之WinForm开发

    本章简言 上一章笔者介绍了关于WinForm环境.这一章笔者将继续讲WinForm.只不过更加的面向开发了.事实就是在学习工具箱里面的控件.对于WinForm开发来讲,企业对他的要求并没有那么高.但是 ...

  2. Java进击C#——应用开发之WinForm环境

    本章简言 上一章笔者讲到关于IO文件操作类,了解如何处理文件流.从这一章开始笔者将讲解相对比较高级的知识点.而本章笔者就对WinForm开发的知识点进行讲解和引导.现在很多业务都是面向于B/S模式的开 ...

  3. 应用开发之WinForm环境

    本章简言 上一章笔者讲到关于IO文件操作类,了解如何处理文件流.从这一章开始笔者将讲解相对比较高级的知识点.而本章笔者就对WinForm开发的知识点进行讲解和引导.现在很多业务都是面向于B/S模式的开 ...

  4. Android 开发之 Android 开发的起步

    前言  Android 开发的起步 我们可以先来看看百科上面怎么说? 百度百科上 Android的介绍 一.Windows环境下在线搭建Android环境. 1. 下载 Android开发工具. JD ...

  5. 新人大餐:2018最新Office插件开发之ExcelDNA开发XLL插件免费教学视频,五分钟包教包会

    原始链接:https://www.cnblogs.com/Charltsing/p/ExcelDnaVideoCourse.html QQ: 564955427 先解释一下,为什么要做这个视频: 我在 ...

  6. bsp开发之OAL开发

    windows ce 操作系统移植主要包含两个方面:一个是基于cpu级的.还有一个是基于开发板级的.cpu级的主要由微软或者芯片制造商来完毕.开发板级的移植主要是由OEM来完毕的,而OAL的开发正是O ...

  7. 多端开发之uniapp开发app

    最近在给f做一些工具app,学习了不少关于uniapp编写android应用的知识. 首先,App应用的创建的时候要选择项目类型为uniapp类型.最开始我选择的是h5+项目,这种项目就比较容易写成纯 ...

  8. PDMS二次开发之PML开发一些常见查询语句

    1.查找session 以及session number var !DBname DBname !db = object db(!DBname) !session = !db.lastsession( ...

  9. iOS开发之XMPPFramework开发基础介绍

    1 使用iPhoneXMPP实例 2 修改xmppstream设置 3 基础协议的介绍 协议 协议简介 XEP-0009 在两个XMPP实体间传输XML-RPC编码请求和响应 XEP-0006 使能与 ...

随机推荐

  1. Ubuntu分区方案归总

     更新时间:2010-8-26   一.各文件及文件夹的定义 /bin:bin是binary(二进制)的缩写.存放必要的命令  存放增加的用户程序. /bin分区,存放标准系统实用程序. /boot: ...

  2. 搭建coreseek(sphinx+mmseg3)详细安装配置+php之sphinx扩展安装+php调用示例(转)

    一个文档包含了安装.增量备份.扩展.api调用示例,省去了查找大量文章的时间. 搭建coreseek(sphinx+mmseg3)安装 [第一步] 先安装mmseg3 cd /var/install ...

  3. Android中 单位 介绍

    看到有很多网友不太理解dp.sp和px的区别:现在这里介绍一下dp和sp.dp也就是dip.这个和sp基本类似.如果设置表示长度.高度等属性时可以使用dp 或sp.但如果设置字体,需要使用sp.dp是 ...

  4. Ajax异步打开新页面弹框被拦截,无法将参数值传递到后台

    一.Form提交,打开新页面被拦截 手动触发Form提交打开新页面是不会被拦截的,但是如果通过Ajax异步处理回调后再程序自动触发Form提交的话,就会被浏览器当成广告弹框拦截 1.暂时的解决办法:如 ...

  5. 阿里云 部署并开启nodejs应用

    1.下载资源  $ wget https://nodejs.org/dist/v8.11.2/node-v8.11.2-linux-x64.tar.xz 2.xz解压 $ xz -d node-v8. ...

  6. mysqldump全量备份+mysqlbinlog二进制日志增量备份

    日常的数据备份及恢复测试,是DBA工作重中之重的事情,所以要做好备份及测试,日常的备份常见有mysqldump+binlog备份.xtrabackup+binlog备份,无论那一种,几乎都少不了对bi ...

  7. jquery操作复选框(checkbox)十二技巧

    jquery操作复选框(checkbox)的12个小技巧. 1.获取单个checkbox选中项(三种写法)$("input:checkbox:checked").val()或者$( ...

  8. [svc]nfs客户端报错解决Stale file handle

    NFS故障: 问题背景: 客户端挂载是好的.服务端磁盘满了,重新给挂了一快.客户端df -h 发现nfs挂载消失. 查看目录客户端报错:Stale file handle 现象如下: [root@n1 ...

  9. 每日英语:Do Bicycle Helmet Laws Really Make Riders Safer?

    Typically in transportation — and most social arenas, for that matter — laws promoting safety precau ...

  10. 为什么 Windows API 使用 stdcall 调用约定?

    作者:知乎用户链接:https://www.zhihu.com/question/31453641/answer/52001143来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...