`

WinForm二三事(四)界面布局(上)

 
阅读更多

记得刚从Web转向WinForm开发时有一段狂喜,没有Session丢失、没有浏览器不兼容,不用围着HTML、CSS、Javascript、C#打转,在Visual Studio里控件摆成什么样子最后就是什么样子(虽然根据最终用户的操作系统和分辨率设置有稍微的不同),这种感觉好久没有过了,但随着开发的界面越来越复杂却有些无措。

接下来我会分两篇来介绍WinForm界面布局中需要注意的一些事情,上篇介绍的是一些简单但也常见的,而下篇会接触更为复杂但灵活的内容。

Dock & Anchor

Dock和Anchor是水火不容的,同时给控件设置Dock和Anchor属性时后设置的会覆盖前面的设置。

Dock

我初接触WinForm的时候发现控件的Width和Height只能是int,不能设置为百分比,那个时候就想子控件如何跟着父控件而变化呢?父控件变大就变大,而且还填满那个区域。甚至以为这个需要通过代码来解决,如是在SizeChanged事件里……

后来才发现我要的就是Dock给的,Dock是停靠的意思。Dock属性的类型是DockStyle枚举:

   1: public enum DockStyle
   2: {
   3:     None = 0,
   4:     Top = 1,
   5:     Bottom = 2,
   6:     Left = 3,
   7:     Right = 4,
   8:     Fill = 5
   9: }

默认是None,当为Left的时,就表示子控件停靠在父控件的左边区域,并把左区域填充满: 
image

上图中的Panel总是会停靠在Form的左边区域,不管如何调整Form的高度,它总是能把左边区域填满。Dock麻烦的地方在于多个控件碰到一起时,比如有两个Panel都设置为Left该怎么办?我们会发现向父控件的Controls集合中添加子控件,越晚添加具有更高的“优先级”(不知道有没有这个说法,这是我杜撰的)。这里的优先级指的是,子控件“优先级”越高,越靠近父控件边缘,其他子控件就得避让:

this.Controls.Add(this.panel1); 
this.Controls.Add(this.panel2);

 image

Panel2后添加进去,所以它具有更高的优先级,更靠近Form的边缘。这个规则不仅仅对于Dock都设为Left的有效,对Dock属性不同,但是碰到一起的子控件也适用:

   1: this.panel1.Dock = DockStyle.Left;
   2: this.panel2.Dock = DockStyle.Left;
   3: this.panel3.Dock = DockStyle.Top;
   4:  
   5: this.Controls.Add(this.panel1);
   6: this.Controls.Add(this.panel2);
   7: this.Controls.Add(this.panel3);

panel3的Dock设置为Top,最后添加到Controls集合中,所以具有最高的优先级,其他两个panel都得避让:  
image

将Panel3调整成第二个添加进去呢?却是这番景象:  
image

当然,这里的“优先级”比较只在同一个“层次”起作用,将子控件与父控件同一层次的控件相比较是没有意义的。

Anchor

Dock一般是划分区域的,将一个窗体或大控件划分几个大区域以便布局,就像Web中的div一样。但有的时候我们却想子控件在父控件里的相对位置不要随着父控件的变大缩小而变化,或者控件边缘距离父控件边缘的相对距离不要发生变化,但又不是停靠在父控件的边缘,这就是Anchor该出场的时候了。

Anchor属性的类型是AnchorStyles位标记(如果不理解位标记就将其理解为可以使用位运算符进行操作,从而可以设置多个值的枚举吧,深入理解请参见MSDN或《CLR via C#》中对位标记的描述):

   1: [Flags]
   2: public enum AnchorStyles
   3: {
   4:     None = 0,
   5:     Top = 1,
   6:     Bottom = 2,
   7:     Left = 3,
   8:     Right = 4
   9: }

Anchor的默认值是Anchor.Left | Anchor.Top,也就是子控件与父控件的左边缘和上边缘的相对位置不会变化,这也保证了在窗体最大化后子控件的位置不会发生变化:

窗体默认显示时->

image

窗体变大后->

 image 
还是悬停在左上角不会发生变化。那如果设置为Left和Right呢?当Anchor设置为Left|Right的时候,为了确保父控件(在这里就是Form)变大时,控件的边缘与父控件距离不变,子控件会自动的扩大:

image

总之,记着Anchor的中文意思:锚。当给控件设置Anchor的时候,就相当于用一个铁钉将控件的边缘给钉住。

Padding & Margin

Padding和Margin没有什么好说的,和CSS的盒模型描述的一模一样,Padding指的是控件内部空间,Margin指的是控件之外的:

image

padding和margin都可以指定四个值。

AutoSize

有的时候我们需要控件随着里面的内容的增长而增长,比如在做多语言的程序时,各国的语言描述同一个意思的时候长度会不同,这个时候就需要AutoSize为true了,这样当文字过长不会被截断。关于AutoSize更详细的内容请参见MSDN

如何面对复杂界面?出了问题咋办?

设计时

当界面变得越来越复杂的时候,我们很期望了解控件之间的层次关系,这个按钮是放在哪个Panel上?这个Panel的区域又是咋样的。我刚接触WinForm的时候,我非常期望WinForm上也有类似于IE Developer Toolbar的工具,点击HTML,可以可视化的在界面上显示区域,在界面上选中某区域,也可以定位到HTML元素。实际上在设计WinForm界面时也是可以的。这就是Visual Studio的Document Outline窗口(View->Other Windows->Document Outline):

image

不过如果你只想顺着button1->panel4->panel3->……这条线导航控件树,有更方便的方法:ESC键。选中一个控件,然后敲ESC键就会顺着这个控件层次不断的上溯。

选中一个控件,然后点击右键,还会出现 Select …的菜单,可以选中该控件的某个父控件:

image

真是够方便的~~~

运行时

不过有个问题是,上面的方法都是设计时的,有的时候我们的程序中如果动态的修改了某些涉及布局的属性最后发现界面乱套了,这可咋整。运行时的问题当然要运行时解决,给某个父控件附加Layout事件,当修改了涉及Layout的属性时会触发这个事件(也有特例,下一节介绍)。这个事件会有一个LayoutEventArgs参数,该参数有AffectedProperty属性,该属性指示的就是影响布局的罪魁祸首,你就找到病症所在了。

SuspendLayout & ResumeLayout

我想大家对这两个方法肯定不默认,几乎在WinForm里的InitializeComponent方法里,在方法开始处有会调用SuspendLayout方法,然后在方法快结束处会调用ResumeLayout方法。有些的读者也许还尝试过删除这两个方法,发现程序表现行为和以前也一样。

了解这两个方法对WinForm程序的性能还是挺有帮助的,在上一节提到修改涉及Layout的属性时会触发Layout事件,但是有特例,特例就是调用了SuspendLayout方法,关于修改哪些属性会触发Layout事件请查阅MSDN。在代码中如果修改Size、Dock等属性或向父控件添加子控件时,会执行布局逻辑,有的时候甚至会重绘。当我们要修改一堆的这样的属性时,比如前面提到的InitializeComponent方法,我们当然不想修改一下就执行一次布局逻辑,那太慢了。这个时候在修改之前你就可以调用SuspendLayout方法挂起布局逻辑,等所有属性都设置好后再调用ResumeLayout属性,特别是在界面很复杂的时候性能有很大的提升。

Visual Studio默认将设置这些属性的语句全部放在InitializeComponent方法里,然后用SuspendLayout和ResumeLayout括住,所以我们一般不要自作主张的将这些属性移出到外面设置,不过有的时候我们想在代码里动态生成一些界面,比如添加一些子控件什么的,我们最好也像VS干的那样调用这两个方法。

要注意的是,并不是调用了Form的SuspendLayout和ResumeLayout方法就一了百了了。如果你是向一个Panel添加子控件,你还得调用Panel的这两个方法。

总结

本文介绍了WinForm界面布局的初步知识,还介绍了通过临时挂起布局逻辑来优化程序性能。这些都很基础也很简单,应付简单的布局是够了,不过对于更灵活更复杂的布局就要涉及布局引擎的内容了,这个我会在下一节里介绍。

转自:http://www.cnblogs.com/yuyijq/archive/2010/01/20/1652082.html

作者:横刀天笑

分享到:
评论

相关推荐

    Winform 界面布局详解

    Winform 界面布局详解 Winform 界面布局是指在 Windows 窗体应用程序中对控件的排列和布局,目的是为了让控件在父控件中能够自动地适应大小和位置的变化。Dock 和 Anchor 是两种常用的布局方式,它们可以单独使用,...

    winform 使用Anchor属性进行界面布局的方法详解

    在Windows Forms开发中,界面布局是一项重要的任务,它决定了用户界面在不同屏幕尺寸和分辨率下显示的美观性和可用性。`Anchor`属性是WinForm中一个非常实用的工具,用于控制控件如何随着窗体的大小调整而自动调整其...

    C#Winform界面布局设计(左侧菜单)右侧窗口操作

    本主题聚焦于使用C#进行Winform界面布局设计,特别是实现左侧菜单和右侧窗口的操作。Winform是.NET Framework提供的一个强大的用户界面设计工具,它允许开发者创建具有丰富功能的桌面应用。 首先,我们要理解...

    C#winform制作绚丽的Ui界面

    三、界面布局 1. 布局容器:WinForm提供了多种布局容器,如FlowLayoutPanel、TableLayoutPanel和StackPanel,它们可以帮助开发者方便地管理控件的位置和大小,实现响应式布局。 2. 设计工具:Visual Studio的Design ...

    C#之模仿office界面布局程序框架winForm

    首先,我们来看看C# WinForm界面布局。WinForm是.NET Framework提供的用于创建桌面应用的窗口化用户界面的库。它提供了丰富的控件集,如Button、TextBox、Label等,以及灵活的布局管理器,如FlowLayoutPanel和...

    C# 界面布局 winform

    下面我们将深入探讨C# WinForm界面布局的相关知识点。 一、WinForm界面设计基础 WinForm提供了多种控件,如Button、Label、TextBox、PictureBox等,用于构建应用程序的用户界面。开发者可以使用Visual Studio的拖放...

    DockForm_C#winform界面设计_winform界面_winform_源码.rar.rar

    本文将深入探讨DockForm这一组件在WinForm界面设计中的应用,以及如何通过源码实现高效、美观的界面布局。 DockForm是.NET Framework中Windows Forms库提供的一种窗口定位和布局机制,允许开发者将控件固定在窗体的...

    仿VS布局的WinformUI控件

    【描述】"最新的DockPanel组件"是描述中提到的关键技术,它是一种能够模仿Visual Studio不同版本(如VS2003、2005、2012、2013、2015等)界面布局的第三方控件。这个组件提供了高度灵活的界面设计能力,允许开发者...

    C# winform也可以实现很好看的界面(源码)

    在布局设计上,使用`TableLayoutPanel`或`FlowLayoutPanel`可以帮助我们更好地组织控件,实现灵活的网格布局或流式布局。通过设置控件的Dock属性,可以使其填充容器的某一边或全部,达到现代应用常见的全屏布局效果...

    winform.zip_c#winform_winform_winform 界面_winform界面

    在本资源"winform.zip"中,包含了470多个WinForm界面特效的例子,这是一份非常适合C# WinForm初学者的学习资料。下面将详细阐述WinForm、C#以及WinForm界面设计的相关知识点。 1. C# WinForm基础: - C#:C#是一种...

    winform高仿qq登陆界面

    2. `FrmLogin.Designer.cs`:这是一个自动生成的文件,包含了WinForm设计时的代码,用于管理FrmLogin窗体的布局和控件属性。 3. `FrmLogin.cs`:这是FrmLogin窗体的主要代码文件,包含了窗体的逻辑和事件处理程序,...

    Winform QQ登录界面源码

    在这个项目中,我们将不依赖任何第三方控件,完全依靠内置的Winform组件来实现QQ登录界面的效果。 首先,我们需要了解Winform中的基本控件,如Label、TextBox、PictureBox和Button等。在模仿QQ登录界面时,我们会...

    Winform仿360安全卫士红色界面风格

    【标题】"Winform仿360安全卫士红色界面风格"所涉及的知识点主要集中在Windows桌面应用程序开发领域,特别是使用Microsoft Visual Studio 2008和C#编程语言来创建用户界面。360安全卫士是一款广为人知的安全软件,其...

    C# Winform 仿360杀毒软件界面

    在本文中,我们将深入探讨如何使用C# Winform来创建一个仿360杀毒软件的用户界面。Winform是.NET Framework中用于构建桌面应用程序的一种技术,它提供了丰富的控件和设计工具,使得开发者能够创建出功能强大且美观的...

    C# Winform 界面 CSkin 高仿360手机界面

    在本文中,我们将深入探讨如何使用C# Winform结合CSkin库来创建一个高仿360手机界面的桌面应用程序。CSkin库是一款强大的界面美化工具,它允许开发者轻松地为Windows Forms应用添加各种风格的皮肤,使得界面更加美观...

    winform 使用html做界面

    总的来说,将HTML应用于WinForm界面设计,不仅可以利用Web技术的灵活性和丰富性,还能使WinForm应用的界面更加现代化,提高用户体验。同时,合理管理和优化资源,以及选择合适的Web渲染引擎,对于实现高效、兼容的...

    winform VS窗口布局的框架 灵活拖拽布局

    在Windows Forms(Winform)开发中,创建美观且可自定义布局的用户界面是一项重要的任务。Visual Studio(VS)提供了一种强大的工具,允许开发者构建这样的界面,但是默认的布局管理有时并不能满足所有复杂的需求。...

    DesignerHosting winform设计器

    "DesignerHosting WinForm设计器"是一款专门针对微软WinForm平台的开发工具,它为开发者提供了一个强大的设计环境,便于创建和管理用户自定义的控件以及WinForm应用程序的界面布局。这款设计器不仅支持基本的WinForm...

    WinForm界面布局控件WeifenLuo.WinFormsUI.Docking

    WeifenLuo.WinFormsUI.Docking是WinForm的一种开源界面布局控件简单易用, 用过的人都深有体会,该控件之强大、美观、不亚于商业控件。而且控件使用也是比较简单的。先看看控件使用的程序界面展示效果。

    CSkin WinForm 登录界面美化设计Demo

    CSkin是一个专门用于提升.NET Framework下WinForm界面视觉效果的组件库,它可以帮助开发者轻松实现美观、现代感十足的用户界面。下面,我们将详细讲解CSkin组件的核心特性、如何集成到项目中以及如何设计一个...

Global site tag (gtag.js) - Google Analytics