WPF布局全接触
- 格式:docx
- 大小:759.14 KB
- 文档页数:34
WPF教程⼆:布局之StackPanel⾯板应⽤程序界⾯设计中,合理的元素布局⾄关重要,它可以⽅便⽤户使⽤,并将信息清晰合理地展现给⽤户。
WPF提供了⼀套功能强⼤的⼯具-⾯板(Panel),来控制⽤户界⾯的布局。
你可以使⽤这些⾯板控件来排布元素。
如果内置布局控件不能满⾜需要的话,还可以创建⾃定义的布局元素。
⾯板(Panel)WPF⽤于布局的⾯板主要有6个,StackPanel(栈⾯板)、WrapPanel(环绕⾯板)。
DockPanel(停靠⾯板)、Canvas(画布)、Grid(⽹格⾯板)和UniformGrid(均布⽹格)。
StackPanel:栈⾯板栈⾯板,可以将元素排列成⼀⾏或者⼀列,其特点是:每个元素各占⼀⾏或者⼀列,Orientation属性指定排列⽅式:Vertical(垂直)【默认】、Horizontal(⽔平),默认情况下,⽔平排列时,每个元素都与⾯板⼀样⾼;垂直排列时,每个元素都与⾯板⼀样宽。
如果包含的元素超过了⾯板空间,它只会截断多出的内容。
元素的Margin属性⽤于使元素之间产⽣⼀定得间隔,当元素空间⼤于其内容的空间时,剩余空间将由HorizontalAlignment和 VerticalAlignment属性来决定如何分配。
1、垂直⽅向排列界⾯运⾏效果:使⽤XAML代码实现:1 <Window x:Class="WpfDemo.MainWindow"2 xmlns="/winfx/2006/xaml/presentation"3 xmlns:x="/winfx/2006/xaml"4 Title="StackPanel⾯板" Height="237" Width="525" WindowStartupLocation="CenterScreen">5 <StackPanel x:Name="stackpanel" Margin="0" Orientation="Vertical">6 <Button Content="第⼀个"></Button>7 <Button Content="第⼆个"></Button>8 <Button Content="第三个"></Button>9 <Button Content="第四个"></Button>10 </StackPanel>11 </Window>2、⽔平⽅向排列界⾯运⾏效果:使⽤XAML代码实现:1 <Window x:Class="WpfDemo.MainWindow"2 xmlns="/winfx/2006/xaml/presentation"3 xmlns:x="/winfx/2006/xaml"4 Title="StackPanel⾯板" Height="237" Width="525" WindowStartupLocation="CenterScreen">5 <StackPanel x:Name="stackpanel" Margin="0" Orientation="Horizontal">6 <Button Content="第⼀个"></Button>7 <Button Content="第⼆个"></Button>8 <Button Content="第三个"></Button>9 <Button Content="第四个"></Button>10 </StackPanel>11 </Window>注:当把StackPanel的FlowDirection属性设置为RightToLeft,Orientation属性设置为Horizontal,StackPanel将从右向左排列元素。
WPF使用一WPF界面布局首先会看到一个靓丽的小方框,将鼠标放在方框的边缘点击就会产生相应的分割线。
现在我们要做的内容需要将窗体分成三行,可以先随便分割一下,以后在调整相互的大小。
这时候会注意到下方的XML代码区域。
每个R owDefinition作为一个行被定义出来会使控件在一定的坐标上固定位置以下WPF中的布局观(Layout Phil osophy):在WPF窗体中,一个窗体只能持有一个控件,当多个控件想要在窗体中展现时,就需要首先设置一个容器控件(Container)然后将其他控件放到这个控件里面,形成树状结构因此,布局观第一条就是,控件的布局应该有容器来决定而不是通过自身使用margin之类的东西来控制位置。
因为这些属性原本应该是控制自己内部展现或与邻里之间关系的;第二条,控件应避免明确的定义具体的尺寸,因为显示器分辨率及windows窗体的大小都有可能随时改变通过MinWidth,MinHeight,MaxWidth,MaxHeight属性可以实现这一点第三条,不要将界面元素位置设置成与屏幕坐标相关.现在显示器分辨率比较多样话(800×600、1024×768,我的显示器是一台是1400×1050,还有一个是1024×1280竖式的),这样的做法还是比较有风险的。
第四条,容器应将有效空间共享给其子控件,这也是为了不在窗体调整后,遗留出大块的空余。
第五条,容器嵌套使用,因为不同的容器,表现效果不同,必要时应结合使用。
接下来在工具箱(Tool Box)中双击ListView,一个小框会出现在界面上。
接下来在工具箱(Tool Box)中双击WrapPanel,又一个大框会出现在界面上。
再增加一个Button。
最终结果如下:<Grid><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/><RowDefinition Height="22"/></Grid.RowDefinitions><ListView Name="listView1"MinWidth="280"><ListView.View><GridView x:Name="gridView1"><GridViewColumn Header="ContactID"></ GridViewColumn><GridViewColumn Header="FirstName"></ GridViewColumn><GridViewColumn Header="LastName"></G ridViewColumn><GridViewColumn Header="EmailAddress "></GridViewColumn></GridView></ListView.View></ListView><WrapPanel Grid.Row="1"Orientation="Horizontal"></WrapPane l><Button Grid.Row="2"HorizontalAlignment="Right"Click="but ton1_Click"Name="button1">Refresh</Button></Grid>1)介绍以下容器控件Panel,现在界面中有两个容器型的控件一个是Grid跟元素,另一个是WrapPanel。
一.摘要首先很高兴这个系列能得到大家的关注和支持,这段时间一直在研究Windows Azure,所以暂缓了更新,同时也本着想把它写好、宁缺毋滥的精神,在速度上自然也就慢了下来,这篇文章拖拖拉拉也经历了十多天才发布出来(每天写一点),不过请大家放心,这个系列一定会继续写下去。
由于自己才疏学浅且是对这些技术的使用总结和心得体会,错误之处在所难免,怀着技术交流的心态,在这里发表出来,所以希望大家能够多多指点,这样在使一部分人受益的同时也能纠正我的错误观点,以便和各位共同提高。
这篇文章主要是对WPF布局系统做一个较简单的介绍,大家都知道:UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,再怎么强大的功能也会显得这个软件很脆弱且没有投资价值。
本文以总分总的形式展开介绍:首先对WPF Panel做一个总体认识、然后讲解各Panel基本用法(分别用XAML和C#两种方式实现同一个功能,便于大家学习)、布局综合应用、自定义布局控件以及最后的总结,希望对大家有所帮助。
二.本文提纲·1.摘要·2.本文提纲·3.总体介绍·4.Canvas·5.StackPanel·6.WrapPanel·7.DockPanel·8.Grid·9.UniformGrid·10.ViewBox·11.Border·12.ScrollViewer·13.布局综合应用·14.自定义布局控件·15.本文总结·16.系列进度·17.相关代码三.总体介绍WPF的布局控件都在System.Windows.Controls.Panel这个基类下面,使用Panel元素在WPF应用程序中放置和排列子对象。
它具体包括哪些布局控件以及如何使用这些布局控件(分别用XAML和C#两种方式实现同一个功能)、如何开发自定义的布局控件,也就是本文所要讨论的范畴:Panel具体继承关系详见下面类图:如上图,公共属性太多了,就简单介绍几个常见的属性:Margin是元素与其他元素的外边距;Padding是指在本元素内部的元素内容与边缘的距离;前面这两个元素基本和ASP.NE中的Margin和Padding类似,只是定义大小的设置不同而已;FlowDirection属性标示元素的内容显示方向;Panel.ZIndex是相对于显示屏的Z轴坐标,用于调整层叠元素的显示先后;RenderTransform和LayoutTransform用来将缩放和旋转的变换应用到某个元素上。
wpf开发操作技巧WPF (Windows Presentation Foundation) 是一种用于创建Windows 应用程序的框架,它提供了丰富的功能和灵活性。
在WPF 开发过程中,有一些操作技巧可以帮助提高开发效率和代码质量。
1. MVVM 设计模式:使用MVVM (Model-View-ViewModel) 设计模式可以帮助你更好地组织和管理你的WPF 应用程序。
MVVM 将应用程序分为三个主要部分:Model(数据模型),View(用户界面)和ViewModel(视图模型)。
ViewModel 充当View 和Model 之间的中间层,负责处理数据绑定和交互逻辑。
使用MVVM 可以使代码更易于维护、测试和重用。
2. 数据绑定:WPF 提供了强大的数据绑定机制,可以将数据与用户界面元素进行关联。
使用数据绑定可以使界面与数据保持同步,简化代码,并提高代码的可读性和可维护性。
掌握数据绑定的各种技巧,如单向和双向绑定、属性通知和集合绑定,可以大大提高开发效率。
3. 命令:WPF 中的命令机制可以帮助你将用户界面的操作与后台逻辑进行解耦。
通过使用命令,你可以将按钮、菜单项等用户界面元素的操作与相应的命令对象关联起来,而不是直接在代码中处理点击事件。
这样可以使代码更加清晰、可测试和可扩展。
4. 样式和模板:WPF 中的样式和模板机制可以帮助你自定义控件的外观和行为。
通过定义样式和模板,你可以将一组属性和事件应用于多个控件,从而使它们具有一致的外观和行为。
使用样式和模板可以减少重复的代码,并提高应用程序的可维护性。
5. 资源:WPF 中的资源机制可以帮助你管理和重用应用程序中的各种资源,如样式、模板、图像和字符串。
通过将资源定义在资源字典中,并使用适当的键进行引用,你可以在整个应用程序中共享和重用这些资源。
这样可以提高应用程序的性能,并使代码更具可读性和可维护性。
6. 动画和过渡效果:WPF 提供了丰富的动画和过渡效果,可以为应用程序添加生动和吸引人的用户体验。
wpf 常用控件和使用方法WPF(Windows Presentation Foundation)是一种用于创建用户界面的框架,它提供了丰富的控件库和强大的功能,使开发人员能够轻松构建现代化的应用程序。
本文将介绍WPF中常用的控件和它们的使用方法。
一、Button(按钮)Button是WPF中最基本的控件之一,用于触发操作或执行命令。
它可以显示文本、图像或两者的组合。
创建一个Button控件很简单,只需在XAML中添加<Button>标签,并设置相应的属性即可。
例如:```<Button Content="Click me!" Click="Button_Click" />```这里,Content属性设置按钮显示的文本,Click属性指定按钮被点击时触发的事件。
我们可以在代码中编写Button_Click方法来处理按钮点击事件。
二、TextBox(文本框)TextBox用于输入和显示文本。
它允许用户在界面中输入文本,并可以通过绑定来实时获取或设置文本的值。
创建一个TextBox控件同样很简单,只需在XAML中添加<TextBox>标签,并设置相应的属性。
例如:```<TextBox Text="{Binding UserName}" />```这里,Text属性用于绑定文本框的值到一个名为UserName的属性。
通过这种方式,我们可以方便地获取和修改文本框中的内容。
三、ComboBox(下拉框)ComboBox用于从预定义的选项中选择一个值。
它可以显示一个下拉列表,用户可以通过点击该列表选择一个选项。
创建一个ComboBox控件同样很简单,只需在XAML中添加<ComboBox>标签,并设置相应的属性和选项。
例如:```<ComboBox SelectedItem="{Binding SelectedItem}" ><ComboBoxItem Content="Option 1" /><ComboBoxItem Content="Option 2" /><ComboBoxItem Content="Option 3" /></ComboBox>```这里,SelectedItem属性用于绑定选中的选项到一个名为SelectedItem的属性。
预期读者1. 初学者。
2. 懒得总结的人。
:)3. 想大致了解WPF框架主要类的功能的人。
前言学习WPF也有段时间了,今天把学到的东西整理一下,主要还是学自MSDN。
下面,我就WPF中最重要的继承线上的几个类列一下,并归纳下它们的功能和使用场景:Object(托管代码)首当其冲的,自然是System.Object类了。
这里主要想说的是,WPF的大部分代码都是使用托管代码编写,原因是因为CLR的许多不错的特性(如内存管理、错误处理、通用类型系统等。
),可以让开发的程序更有效、更健壮。
但是,框架并不是所有代码都是托管的,也有一部分是由非托管代码编写。
原因主要是因为WPF是展现层框架,它的显示需要和DirectX很紧密的集成起来,进行硬渲染和软渲染,以得到性能上的提升。
下面的结构图中,红色部分是属于WPF框架的。
其中,只有milcore这个部分是采用非托管代码编写。
所以,可以看出,我们在使用WPF的时候,是不会接触到里面的非托管代码的。
DispatcherObject(异步)命令空间:System.Threading。
WPF Dispatcher使用User32的消息机制来实现跨线程调用。
工作机制类似Win32的消息泵。
WPF的线程模型和User32的线程模型保持一致,使用STA。
主要原因是互可操作性,因为现在的很多系统都是需要STA的,如IE、OLE2.0、剪贴板等。
通过Dispatcher,我们可以实现线程间的通信。
继承自DispatcherObejct的类,都获取了一个所在线程的Dispatcher 引用,这样,任何使用这个类的对象的线程,都可以使用它的Dispatcher来发送“消息”。
一般情况下,我们使用这个类的意图主要是异步线程调用DispatcherObject的Dispather来让DispatcherObject 的创建线程做一些特定的事情,如设置界面上某个值。
这样大大方便了我们开发人员。
WPF控件和布局,根据刘铁猛《深入浅出WPF》书籍讲解内容,主要记录控件和布局的原理,如果有不足的地方,请大牛们键盘下留情--轻喷!如果还算有用,请给点动力,支持一把!一、WPF里的控件1.1 控件的实质我们先从UI上分析,UI的功能是让用户观察和操作数据,为了能显示数据和响应用户的操作通知程序(通过事件来通知,如何处理事件又是一系列的算法),所以控件就是显示数据和响应用户操作的UI元素,也即:控件就是数据和行为的载体。
1.2 WPF中的一个重要概念--数据驱动UI什么是数据驱动UI呢?我们知道传统的GUI界面都是由windows消息通过事件传递给程序,程序根据不同的操作来表达出不同的数据体现在UI界面上,这样数据在某种程度上来说,受到很大的限制。
WPF中是数据驱动UI,数据是核心,处于主动的,UI从属于数据并表达数据,是被动的。
因为以后的章节会重点介绍,在此不做过多的说明,只要记着,WPF数据第一,控件第二。
1.3 WPF中控件的知多少虽然控件没有数据重要,但是还是比较重要的,毕竟是门面啊,只是在数据面前,它比较"有礼貌"。
控件有很多,但是如果仔细去分析,也是有规律可循的,根据其作用,我们可以把控件分为6类:•布局控件:是可以容纳多个控件或者嵌套其他布局的控件,用于在UI上组织和排列控件。
其父类为Panel。
•内容控件:只能容纳一个控件或者布局控件作为他的内容。
所以经常借助布局控件来规划其内容。
其父类为ContentControl。
•带标题内容控件:相当于一个内容控件,但是可以加一个标题,标题部分也可以容纳一个控件或者布局,其父类为HeaderedContentControl。
•条目控件:可以显示一列数据,一般情况下,是数据的类型是相同的。
其共同的基类为ItemsControl。
•带标题的条目控件:和上面的带标题内容控件类同,其基类为HeaderdeItemsControl。
2:WPF的界⾯布局Canvas定义⼀个区域,在该区域中可以使⽤相对于 Canvas 区域的坐标显式定位⼦元素。
它是⼀个存储元素的容器,它不会⾃动调整内部元素的排列及⼤⼩。
不指定元素位置,元素将默认显⽰在画布的左上⽅。
Canvas的主要⽤途是⽤来画图。
Canvas默认不会⾃动裁减超过⾃⾝范围的内容,溢出的内容会显⽰在Canvas外⾯,因为默认 ClipToBounds="False";我们可以设置ClipToBounds="True来裁剪多出的内容。
1. 在窗体中建⽴三个canvas(ca,ca1,ca2),ca1和ca2包含在ca中。
2. 设置ca填充⾊为黄⾊,ca1为绿⾊,ca2为红⾊。
3. 在ca1中放⼊⼀个TextBlock,⼀个Button,⼀个Ellipse。
TextBlock和Button完全包括在ca1中,Ellipse超出ca1。
4. 设置ca2的ClipToBounds=”true”。
5. 在ca2中放⼊⼀个Ellipse,使其超出ca2。
<Canvas Background="yellow" Name="ca"><Canvas Background="green" Height="158" Width="192" Name="ca1"><Button Content="Button" Canvas.Left="55" Canvas.Top="121" Width="75"/><TextBlock Canvas.Left="80" TextWrapping="Wrap" Text="⽩菜" Canvas.Top="66"/><Ellipse Fill="White" Height="87" Canvas.Left="136" Canvas.Top="90" Width="103"/></Canvas><Canvas Height="119" Width="133" Background="red" ClipToBounds="True" Canvas.Left="316" Canvas.Top="157" Name="ca2"><Ellipse Fill="White" Height="87" Canvas.Left="58" Canvas.Top="67" Width="103"/></Canvas></Canvas>StackPanelStackPanel就是将⼦元素按照⼀⾏或者⼀列排列,通过设置Orientation属性设置横排(Horizontal)和竖排(Vertical默认)。
WPF and Silverlight 学习笔记(九):WPF布局管理之Canvas、InkCanvas一、Canvas在WPF中子元素的绝对定位的布局控件∙其子元素使用Width、Height定义元素的宽度和高度∙使用Convas.Left(Convas.Right)、Convas.Top(Convas.Bottom)定义与Convas容器的相对位置∙如果同时存在Convas.Left和Convas.Right、Convas.Top和Convas.Bottom,则Convas.Left、Convas.Top优先生效例如:1:<Canvas>2:<Button Canvas.Left="10"Canvas.Top="10"Height="23"Width="75">LT</Button>3:<Button Canvas.Right="10"Canvas.Top="10"Height="23"Width="75">RT</Button>4:<Button Canvas.Left="10"Canvas.Bottom="10"Height="23"Width="75">LB</Button>5:<Button Canvas.Right="10"Canvas.Bottom="10"Height="23"Width="75">RB</Button>6:</Canvas>在调整窗体大小时,LT与左、上距离保持不变;RT与右、上距离保持不变;LB与左、下距离保持不变;RB与右、下距离保持不变。
WPF中常⽤的布局容器介绍⽬录⼀、简介⼆、代码案例1.Border2.StackPanel3.WrapPanel4.DockPanel5.Grid6.UniformGrid7.Canvas8.ScrollViewer⼀、简介所有的WPF布局容器都派⽣⾃System.Windows.Controls.Panel。
Panel继承⾃FrameworkElement。
在Panel中有⼀个⽐较重要的属性是UIElementCollection 类型的Children属性,UIElementCollection 是⼀个有序的集合。
我们可以使⽤继承⾃Panel的类来重写MeasureOverride(),ArrangeOverride()实现⾃定义⾯板。
常⽤的布局容器:Border不是布局⾯板,但是经过⼏个⼤佬的提醒,⽤好他真的很重要,所以我就放在第⼀个了。
StackPanel: 堆栈⾯板,⽔平或垂直放置元素。
WrapPanel:可换⾏的⾏中放置元素,在⽔平⽅向上从左向右放置元素,换⾏后也是从左向右。
在垂直⽅向上,从上到下放置元素,在切换列后也是从上到下。
DockPanel: 根据容器的整个边界调整元素。
Grid:在⾏列表格中排列元素。
UniformGrid:强制所有单元格具有相同尺⼨。
Canvas:使⽤固定坐标绝对定位元素。
ScrollViewer:通过添加滚动条可以使当前过长布局内的内容纵向或者横向滚动。
再有限的区域内可以通过滚动呈现更多的内容。
⼆、代码案例1.BorderBorder不是布局⾯板,但是经常与布局类的⾯板⼀起配合使⽤,所以先介绍Border。
Border的主要作⽤是给元素添加边框,这个元素可以理解为⼀个布局⾯板,⼀个控件等等。
他包含设置边框的2个属性,BorderBrush⽤来设置颜⾊,BorderThickness⽤来设置宽度。
CornerRadius设置圆⾓。
⽽Padding和Margin⼀个设置边框和⾥⾯元素的间距,⼀个设置边框和其他临近元素的间距。
WPF中的控件布局WPF中的控件布局WPF提供了丰富的控件,包括:Editing:CheckBox, ComboBox, PasswordBox, RadioButton, RichTextBox, Slider, TextBox.List Selection: ListBox, ListView, TreeView.User Information:Label, ProgressBar, Popup, ToolTip.Action:Button, ContextMenu, Menu, Separator, StatusBar, Thumb, ToolBar.Appearance:Border, BulletDecorator, Decorator, Image, Viewbox.Dialog boxes: OpenFileDialog, PrintDialog, SaveFileDialog.Containers:Expander, GroupBox, RepeatButton, ScrollBar, ScrollViewer, TabControl.Layout:Canvas, DockPanel, Grid, GridSplitter, Panel, StackPanel, VirtualizingStackPanel, WrapPanel.Navigation:Frame, Hyperlink.Documents:DocumentViewer, FlowDocumentPageViewer, FlowDocumentReader, FlowDocumentScrollViewer.Net3.0使用Panel来进行布局.其中继承于Panel的5中布局版面包括: Canvas, DockPanel, Grid, StackPanel, VirtualizingStackPa nel, WrapPanel.1, Cavas:简单地设置坐标值来布局Canvas很单纯地设置其子控件相对于它的Top, Left, Bottom., Ri ght值来进行定位其子控件. 那么请调用相关方法 public static void S etLeft (UIElement element,double length)等假设border1是canvas1的Children, 那么我们应该这样设置bo rder1在canvas1中的位置:Canvas.SetT op(border1, 100);Canvas.SetLeft(border1, 50);注意这里有些奇怪的是调用Cavas的静态方法SetTop,SetLeft.特别地, 当同时设置了Top与Bottom时,只有T op生效;同理同时设置了Left和Right时则只有Left生效,而不会拉伸控件.要设置控件大小请使用控件的Width和Height属性.以下是一个示例:<Page xmlns=/winfx/20 06/xaml/presentation xmlns:sys="clr-namespace:System;assemb ly=mscorlib" xmlns:x="/winfx/20 06/xaml"><Canvas Background="Pink" Name="MyCanvas"><!--定义画布--><Rectangle Height="100" Width="100" Canvas.Top="100 " Canvas.Left="100" Fill="Red"/><Rectangle Height="100" Width="150" Canvas.Top="100 " Canvas.Left="300" Fill="Blue"/><Rectangle Height="100" Width="200" Canvas.Top="100 " Canvas.Left="500" Fill="Yellow"/></Canvas></Page>2,DockPanel: 与.net3.0之前的控件的Dock属性类似.DockPanel为其子控件提供相对的停靠位置, 包括向左停靠(Dock. Left),向右停靠(Dock.Right),向下停靠(Dock.Bottom),向上停靠. 请调用DockPanel的静态方法SetDock(UIElement e, Dock dock) 假设border1是dockPanel1的子控件,那么我们可以这样来设置border1的位置:DockPanel.SetDock(border1, Dock.Left|Dock.Top);以下是一个示例:<Page xmlns="/winfx/2006/x aml/presentation" WindowTitle="DockPanel Sample"><DockPanel LastChildFill="True"><Border Height="25" Background="SkyBlue" BorderBrush= "Black" BorderThickness="1" DockPanel.Dock="T op><TextBlock Foreground="Black">Dock = "Top"</TextBlock> </Border><Border Height="25" Background="SkyBlue" BorderBrush= "Black" BorderThickness="1" DockPanel.Dock="T op"> <TextBlock Foreground="Black">Dock = "Top"</TextBlock> </Border><Border Height="25" Background="LemonChiffon" BorderB rush="Black" BorderThickness="1" DockPanel.Dock="Bottom,Ri ght"><TextBlock Foreground="Black">Dock = "Bottom"</TextBl ock></Border><Border Width="200" Background="PaleGreen" BorderBrus h="Black" BorderThickness="1" DockPanel.Dock="Left"> <TextBlock Foreground="Black">Dock = "Left"</TextBlock> </Border><Border Background="White" BorderBrush="Black" Border Thickness="1"><TextBlock Foreground="Black">This content will "Fill" th e remaining space</TextBlock></Border></DockPanel></Page>3, StackPanel :按照水平线方向或垂直线方向排列控件StackPanel允许你按照指定的方向(HorizontalAlignment, Verti calAlignment)向其中添加子控件.关于StackPanel与DockPanel的区别SDK中是这样阐述的:”Although you can use either DockPanel or StackPanel to stack chil d elements, the two controls do not always produce the same re sults. For example, the order that you place child elements can a ffect the size of child elements in a DockPanel but not in a Stack Panel. This different behavior occurs because StackPanel measur es in the direction of stacking at Double.PositiveInfinity; howeve r, DockPanel measures only the available size.”以下是一个示例:<Page xmlns="/winfx/2006/x aml/presentation" xmlns:sys="clr-namespace:System;assembly= mscorlib" xmlns:x="/winfx/2006/x aml"><Grid><StackPanel Orientation="Horizontal" Background="silver " Margin="20"><Label Margin="5" Content="Username"/><Button Content="123eqweqweq"/><Button Name="test" Width="100" Height="50" Content=" Test"/><Button Content="123eqweqweq"/><Label Name="testlabel" Content="king"/></StackPanel></Grid></Page>4,WrapPanel: 自动换行子控件的布局当子一行(或一列)不足以放置新控件时,WrapPanel将自动地将子控件放置到新行(或新列,这取决于Orientation属性)以下是一个示例:<Windowxmlns="/winfx/2006/xaml/pre sentation"xmlns:x="/winfx/2006/xaml"xml:lang="zh-CN"x:Name="Window"Title="Window1"Width="640" Height="480" xmlns:d="http://schemas.micro /expression/blend/2006" xmlns:mc="/markup-compati bility/2006" mc:Ignorable="d"><Grid x:Name="LayoutRoot"><Grid.RowDefinitions><RowDefinition Height="0.83*"/><RowDefinition Height="0.17*"/></Grid.RowDefinitions>; <WrapPanel x:Name="wrapPanel1"><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Default}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/><Rectangle Fill="#FFAA5E5E" Stroke="#FF000000" Width=" {Binding Path=Value, ElementName=slider1, Mode=Default}" H eight="{Binding Path=Value, ElementName=slider1, Mode=Def ault}"/></WrapPanel><Slider d:LayoutOverrides="Margin" HorizontalAlignment= "Right" Margin="0,19.01,24,29" x:Name="slider1" Width="128 " Grid.Row="1" Maximum="300" Minimum="50" Value="50"/> </Grid></Window>5 Grid:表格布局Grid允许我们通过自定义行列来进行布局,这类似于表格. 我们可以通过表格来进行交复杂框架的布局,然后再在表格内部利用其他布局方式或嵌套表格个方式进行布局.可以通过设置Columns和Rows的属性,通过定义Grid的Colu mnDifinitions和RowDifinitions来实现对于表格的定义,然后根据Grid.Column和Grid.Row的对象来制定位置的方式实现布局.这里是一个示例:<Page xmlns="/winfx/2006/x aml/presentation" WindowTitle="Grid Sample"><Grid VerticalAlignment="Top" HorizontalAlignment="Left " ShowGridLines="True" Width="250" Height="100"> <Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition /><RowDefinition /><RowDefinition /><RowDefinition /></Grid.RowDefinitions><TextBlock FontSize="20" FontWeight="Bold" Grid.Column Span="3" Grid.Row="0">2005 Products Shipped</TextBlock> <TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1 " Grid.Column="0">Quarter 1</T extBlock><TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1 " Grid.Column="1">Quarter 2</T extBlock><TextBlock FontSize="12" FontWeight="Bold" Grid.Row="1 " Grid.Column="2">Quarter 3</T extBlock><TextBlock Grid.Row="2" Grid.Column="0">50000</TextBl ock><TextBlock Grid.Row="2" Grid.Column="1">100000</TextB lock><TextBlock Grid.Row="2" Grid.Column="2">150000</TextB lock><TextBlock FontSize="16" FontWeight="Bold" Grid.Column Span="3" Grid.Row="3">T otal Units: 300000</TextBlock> </Grid></Page>。
WPF布局全接触一.摘要首先很高兴这个系列能得到大家的关注和支持,这段时间一直在研究Windows Azure,所以暂缓了更新,同时也本着想把它写好、宁缺毋滥的精神,在速度上自然也就慢了下来,这篇文章拖拖拉拉也经历了十多天才发布出来(每天写一点),不过请大家放心,这个系列一定会继续写下去。
由于自己才疏学浅且是对这些技术的使用总结和心得体会,错误之处在所难免,怀着技术交流的心态,在这里发表出来,所以希望大家能够多多指点,这样在使一部分人受益的同时也能纠正我的错误观点,以便和各位共同提高。
这篇文章主要是对WPF布局系统做一个较简单的介绍,大家都知道:UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,再怎么强大的功能也会显得这个软件很脆弱且没有投资价值。
本文以总分总的形式展开介绍:首先对WPF Panel做一个总体认识、然后讲解各Panel基本用法、布局综合应用、自定义布局控件以及最后的总结,希望对大家有所帮助。
二.本文提纲· 1.摘要· 2.本文提纲· 3.总体介绍· 4.Canvas· 5.StackPanel· 6.WrapPanel· 7.DockPanel· 8.Grid· 9.UniformGrid· 10.ViewBox· 11.Border· 12.ScrollViewer· 13.布局综合应用· 14.自定义布局控件· 15.本文总结· 16.系列进度三.总体介绍WPF的布局控件都在System.Windows.Controls.Panel这个基类下面,使用Panel 元素在WPF应用程序中放置和排列子对象。
它具体包括哪些布局控件以及如何使用这些布局控件、如何开发自定义的布局控件,也就是本文所要讨论的范畴:Panel具体继承关系详见下面类图:如上图,公共属性太多了,就简单介绍几个常见的属性:Margin是元素与其停放父元素的间距;Padding是指在本元素内部的元素内容与边缘的距离;FlowDirection属性标示元素的内容显示方向;Panel.ZIndex是相对于显示屏的Z轴坐标,用于调整层叠元素的显示先后;RenderTransform 和LayoutTransform用来将缩放和旋转的变换应用到某个元素上。
一个Panel 的呈现是测量和排列Children子元素、然后在屏幕上绘制它们的过程。
所以在布局的过程中会经过一系列的计算,那么Children 越多,执行的计算次数就越多。
如果不需要较为复杂的Panel(如Grid和自定义复杂的Panel),则可以使用构造相对简单的布局(如Canvas、UniformGrid等),这种布局可带来更好的性能。
如果有可能,我们应尽量避免不必要地调用UpdateLayout方法。
每当Panel内的子元素改变其位置时,布局系统就可能触发一个新的处理过程。
对此,了解哪些事件会调用布局系统就很重要,因为不必要的调用可能导致应用程序性能变差。
换句话说,布局是一个递归系统,实现在屏幕上对元素进行大小调整、定位和绘制,然后进行呈现。
具体如下图,要实现控件0的布局,那么先要实现0的子控件01,02...的布局,要实现01的布局,那么得实现01的子控件001,002...的布局,如此循环直到子控件的布局完成后,再完成父控件的布局,最后递归回去直到递归结束,这样整个布局过程就完成了。
布局系统为Children 集合的每个成员完成两个处理过程:测量处理过程(Measure)和排列处理过程(Arrange)。
每个子Panel 均提供自己的MeasureOverride 和ArrangeOverride 方法,以实现自己特定的布局行为。
四. CanvasCanvas比较简单,只是一个存储元素的容器,它不会自动调整内部元素的排列及大小。
不指定元素位置,元素将默认显示在画布的左上方。
Canvas的主要用途是用来画图。
Canvas默认不会自动裁减超过自身范围的内容,即溢出的内容会显示在Canvas外面,这是因为默认ClipToBounds="False";我们可以通过设置ClipToBounds="True来裁剪多出的内容。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:五. StatickPanelStatickPanel就是将子元素按照堆栈的形式一一排列,通过设置面板的Orientation属性设置了两种排列方式:横排(Horizontal默认的)和竖排(Vertical)。
纵向的StatickPanel默认每个元素宽度与面板一样宽,反之横向亦然。
如果包含的元素超过了面板空间,它只会截断多出的内容。
元素的Margin属性用于使元素之间产生一定得间隔,当元素空间大于其内容的空间时,剩余空间将由HorizontalAlignment和VerticalAlignment属性来决定如何分配。
其他属性,大家可以看看如下类图:要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:六. WrapPanelWrapPanel是一个非常简单的面板,从左至右按顺序位置定位子元素,如果排满断开至下一行。
后续排序按照从上至下或从右至左的顺序进行。
WrapPanel面板也提供了Orientation属性设置排列方式,这跟上面的StackPanel基本相似。
不同的是WrapPanel会根据内容自动换行。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:七. DockPanelDockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列。
停靠面板其实就是在WinForm类似于Dock属性的元素。
DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序,最后一个元素填充这个Panel(这个需要设置LastChildFill属性为True)。
对于在DockPanel中的元素的停靠属性可以通过Panel.Dock的附加属性来设置.要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:八. GridGrid和其他各个Panel比较起来,功能最多也最为复杂,它由<Grid.ColumnDefinitions>列元素集和<Grid.RowDefinitions>行元素集合两种元素组成。
而放置在Grid面板中的控件元素都必须显示采用附加属性语法定义其放置所在的行和列,否则元素均默认放置在第0行第0列。
由于Grid 的组成并非简单的添加属性标记来区分行列,这也使得用户在实际应用中可以具体到某一单元格中,所以布局起来就很精细了。
第一种,固定长度——宽度不够,会裁剪,不好用。
单位pixel。
第二种,自动长度——自动匹配列中最长元素的宽度。
第三种,比例长度——*表示占用剩余的全部宽度;两行都是*,将平分剩余宽度;像上面的一个2*,一个*,表示前者2/3宽度。
跨越多行和多列<Rectangle Fill="Silver" Grid.Column="1" Grid.ColumnSpan="3"/>使用Grid.ColumnSpan和Grid.RowSpan附加属性可以让相互间隔的行列合并,所以元素也可以跨越多个单元格。
使用GridSplit控件结合Grid控件实现类似于WinForm中SplitContainer的功能,这个大家在WinForm当中经常用到,我们也不多做介绍。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:九UniformGrid介绍了前面的Grid,接下来的这个UniformGrid 就太简单了,均布网格的是Grid的简化版本,每个单元格的大小相同,不用在定义行列集合。
均布网格每个单元格只能容纳一个元素,将自动按照定义在其内部的元素个数,自动创建行列,并通常保持相同的行列数。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:十. ViewBoxViewBox这个控件通常和其他控件结合起来使用,是WPF中非常有用的控制。
定义一个内容容器,该容器可拉伸和缩放单个子元素以填满可用空间。
一个Viewbox只能具有一个Child。
如果添加一个附加Child,会导致一个运行时ArgumentException错误。
我们用得最多的首先是Stretch 属性,然后是StrctchDirection属性,关于这两个元素,大家可以运行我们的代码,然后改变设置就可以看到效果。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:十一. BorderBorder 是一个装饰的控件,此控件绘制边框及背景,在Border 中只能有一个子控件(这个子控件又可以包含多个子控件)。
Border 的几个重要属性:Background:用用一个Brush 对象来绘制背景;BorderBrush:用一个Brush 对象来绘制边框;BorderThickness:此属性设置Border 边框的大小;CornerRadius:此属性设置Border 的每一个角圆的半径;Padding:此r属性设置Border 里的内容与边框的之间的间隔。
要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:十二. ScrollViewer通常用户界面中的内容比计算机屏幕的显示区域大,大出的部分就会破坏原有的布局。
利用ScrollViewer 控件可以方便地使应用程序中的内容具备滚动功能。
这样大出的部分就可以正常显示出来了。
常用属性、事件和继承关系见下面类图:要实现的效果如下图(用XAML和C#实现同一效果):XAML代码实现:C#代码实现:十三.布局综合应用前面通过十多个小节讲了一些常用Panel的基本用法,那我们这里就简单做一个综合的小例子,通过这个例子,旨在巩固前面的内容,也可以当做一个举一反三的过程。
要实现的效果如下图:XAML代码实现:其实用熟练上面的各个布局控件以后,你会发现布局UI是一件非常容易的事,遇到一个新的UI,你会发现任意一个Panel都可以实现你的需求。
当然对于较复杂且对要求很高的UI,我们也会自定义一些Panel,在下面我们就简单介绍一下自定义布局控件。
十四.自定义布局控件讲到自定义布局控件,我们必须得先谈一下在WPF中自定义控件,在WPF自定义控件你可以选择下图的一些基类作为继承对象,你也可以继承自已有的一些控件,这个就看你的需要了。