C

科技玩点原始事 2024-02-26 22:27:32

在C#的WinForm编程中,避免不了多窗口的应用,说起来也算简单的,但是想熟练运用就麻烦一些,先将我的体会总结如下:

1、调用窗体与被调用窗体

新建一个WinForm项目后,Visual Studio自动生成一个Form1。我们可以再手工再添加一个窗体Form2,设置好其它控件后,利用如下代码,显示新窗体:

Form2 myForm = new Form2();myForm.Show();

这时,Form2就显示出来了。此时,我们称Form1是“调用窗体”,Form2是“被调用”窗体。

当然,也可以代码的方式显示窗体:

Form myform = new Form();myform.Show();

注意:这时两个窗体之间的关系是平等的,没有“父子”关系,也没有包含关系。一般情况下,调用窗体只能访问被调用窗体的属性、方法,但不能访问被调用窗口内部的控件对象。

测试:

Console.WriteLine("父窗体:"+this.Parent);Console.WriteLine("拥有者:" + this.Owner);

一般情况下,都会返回空。

2、窗体的本质

我们用Visual Studio可视化工具制作的窗体,实际上就是一个“类”,是派生于System.Windows.Forms;的特殊类。我们可以看到如下代码:

……public partial Form1 : Form……

由此可见,我们可以直接修改代码中冒号后面的Form,改为我们自己定义的窗体。这个方法可用于程序“皮肤”的自定义。

3、调用窗体访问被调用窗体内部对象

了解窗体也是类以后,我们就可以将被调用窗体的内部对象,“Modifiers”由默认的“private”改为“public”,自定义的变量也如此,这时候调用窗口就可以访问被调用窗体了。

4、被调用窗体访问调用窗体

(1)被动方式,也就是调用窗体主动给被调用窗体一个“接口”

i.调用窗体定义“静态”变量,并将开放的变量复制

ii.在被调用窗体中,使用:调用窗体名.静态变量名.数学(方法)的形式调用

例如:

……//调用窗体public partial Form1 : Form{public static Form1 mainFm;public static Button mainBtn;public Form1(){InitializeComponent();mainFm = this;mainBtn = this.button1;}……//被调用窗体Form1.mainFm.Text = "标题";Form1.mainBtn.Text = "按钮";

(2)被动方式,由被调用窗体直接访问调用窗体

这一点尤其是在编写自定义类库时尤为重要,因为写代码时,无法预料使用类库者,是否会在调用时开放“主动接口”。

i.在调用窗体中,设置public类型的变量,用于接收类库调用时的赋值,可以直接是窗体,也可以是控件。

ii.如果是窗体,就可以在被调用窗口中直接使用,否则可以利用FindForm()获取调用窗体的对象

例如:

//被调用窗体……public Control myPicture;……//调用窗体……Form2 myForm = new Form2();myForm.myPicture = this.pictureBox1;myForm.Show();……//被调用窗体……Console.WriteLine("调用窗体:" + myPicture.FindForm());……5.调用窗体带着被调用窗体移动

在调用窗体的Move事件中,设置被调用窗体的Top、Left的值

6、被调用窗体跟着调用窗体移动//被调用窗体中public Control VideoWindows;//由被调用窗体赋值VideoWindows.Parent.Move += new EventHandler(OSDMove);//监听调用窗口移动事件7、调用窗体包含被调用窗体

如果为了实现另被调用窗口始终覆盖在调用窗口上,可以使用如下两个命令,哪个都行

this.AddOwnedForm(myForm);myForm.Show(this);8、被调用窗体包含于调用窗体中

如果开发类库,就要让被调用窗口自己操作

//被调用窗体

……public Control myPicture;this.Owner = myPicture.FindForm();//设置拥有此窗体的对象。调用窗体,是通过传递过来的控件,再查找改控件所在的窗体获得的……

注意,Owner只接受窗体类型数据,如果是控件类型,需要转换,例如:

this.Owner = (Form)myPicture.Parent;9、被调用窗体覆盖在调用窗体上

参考上面的“包含”关系。如果调用窗体包含了被调用窗体,这时被调用窗体始终覆盖在调用窗体上

10、被调用窗体嵌入调用窗体空间内……Form2 myForm = new Form2();myForm.TopLevel = false;//指示子窗体非顶级窗体this.panel1.Controls.Add(myForm);//将子窗体载入panelmyForm.Show();……11、子窗口显示方式MyForm.Show();MyForm.ShowDialog();

以上两种方式都能显示新窗口,但是第二种类似MessageBox.Show(),它吧调用窗体的进展阻塞了,调用窗口这时不能响应用户操作。

12、窗体循环操作

推荐Time控件,否则效果会出不来,甚至影响调用窗口的使用效果。

13、窗体透明

必须保证窗体的BackColor与TransparencyKey设置一直。异形窗口可采用带有透明信息的PNG图片。

14、控件透明

设置控件的BackColor为Transparent

设置控件的Parent主控件

重新移动调整一下控件位置(非常重要!否则控件不显示!)

如果只需让控件在窗体上透明,只需a)即可。但是如果控件覆盖在pictureBox或panel上,就需要上面的每个步骤了。

因为默认情况下,控件的父控件就是本事说在的窗体,这时BackColor为Transparent就起作用,但是如果覆盖在其它控件上,就需要后面的两个步骤了。

第三个步骤为什么呢?原因也是父控件的问题,默认是窗体,控件的位置就是以窗体为基准。第三个步骤就是让VS重新按照“父”控件为基准再设置一次。

15、其它:

(1)Irisskin皮肤

使用Irisskin类库设置窗体皮肤时,有时个别窗口或者控件,不希望也使用这个皮肤,这时可以对象的将Tag属性设置为9999,这是默认值,如果需要修改,可以在修改SkinEngine控件的DisabledTag属性。

(2)窗体淡出淡入

设置窗体的Opacity值,范围0~1。例如:

//淡出Time控件TimeShowOSDif (this.Opacity < 1){this.Opacity=this.Opacity+0.1;Application.DoEvents();Console.WriteLine(this.Opacity);}else{TimeShowOSD.Enabled = false;}//淡入Time控件TimeHideOSDif (this.Opacity > 0){this.Opacity =this.Opacity-0.1;Application.DoEvents();Console.WriteLine(this.Opacity);}else{TimeHideOSD.Enabled = false;}

(3)防止进程堵塞

Application.DoEvents();

(4)小心Panel

由于Panel是容器,因此如果想让控件覆盖其上,就要在Panel外面画好再用键盘移动过去,否则可能会导致控件进入了Panel中了。

(5)窗体置顶

修改窗体TopMost的值为真

0 阅读:0

科技玩点原始事

简介:感谢大家的关注