WPF学习:2.Layout-Panels-Countainers
在上文《WPF学习:1开始》中:简单介绍了WPF的架构和内部结构,接下来要讨论下写第一个WPF程序的基本知识,如何在window中放置控件,这对于想要开始学WPF的人都是非常简单的。
代码地址:https://files.cnblogs.com/keylei203/2.LayoutDemo.zip
A Window
当新建一个WPF工程时,最引人注意的是Window,Window是负责用户交互和管理windows整个生命周期的主要类,它使用一般的API构建对象。一个Window包含两部分:
1.非用户区域:一般为Window的外边界,如图标,系统菜单,标题栏和边界等。
2. 用户区:WPF的主要部分。用户能够使用WPF定制的部分。
Window种类
1. Window:一个软件主要的,基本的窗口,每一个控件放置在同一个Window内,用户区域可以用XAML定制。
2. NavigationWindow:一种由Window继承的特殊的Window,它的顶部有一个导航panel,假如你让建立一个向导类的窗体就可以使用NavigationWindow,你也可以定制NavigationWindow成你喜欢的样式。
3.Page:和NavigationWindow类似,唯一的区别就是Page能够用Web浏览器打开。
上图表示了Window和NavigationWindow的区别,一般情况下,Navigation应用场合比较少,但是在你的应用程序需要一些特殊处理时可能会派上用处。
让我们讨论下在你的软件中如何使用Page。
Page是用作页面的一些相同的Window。页的导航是非常简单的,页中增加了导航服务使能够方便的在页之间进行导航,导航服务提供Navigating,NavigationFailed,NavigationProgress,NavigationStopped等,你还在导航的时候使用一个进度条,像GoBack,GoForward和
Navigate
等方法都是非常好的方法。
private void Button_Click(object sender, RoutedEventArgs e) { this.NavigationService.Navigate(new Uri("Page2.xaml", UriKind.Relative)); }
更多内容,请参考OverView of Navigation。
Types of Containers
WPF窗体时从ContentControl继承而来。在处理控件的过程中,你可能会遇到一些基础控件。一个ContentControl可能是一个string,一个任意对象或者是像Button
, TextBox等UIElement。让我们一个一个分析:
1.ContentControl: 一个ContentControl可以保存了简单的文本,比如window,button等
2. HeaderedContentControl:和ContentControl差不多,此外它含有一个头文本,比如GroupBox,Expander就是HeaderedContentControl。
3. ItemsControl:ItemsControl 的内容是文本的集合,因此你可以添加任意的元素到ItemsControl,比如ListBox,ListView
4. HeaderedItemsControl:每一个集合都有一个特殊的头文本。一个HeaderedItemsControl是一个保留了内容复杂元素,比如TreeView。
上面的图片显示了文本控件的差别,每一个文本控件包含了文本属性,在XAML中,可以指定文本属性,或者直接指定在标签内指定文本。
<Button Content="This is a Button" />
和
<Button>This is a Button</Button>
效果是一样的,XAML能够自动解析文本内容。
Alignment-Margin-Padding
Alignment,Margin,Padding是对于UI设计3个非常重要的方面。在进一步的了解容器之前,你需要了解一下他们:
1 Alignment:对齐方式。决定了子控件在父控件中的空间位置,有两种对齐方式:
HorizontalAligment:Left,Right,Center和Stretch,默认为Stretch。
VerticalAligment:Top,Center,Bottom和Stretch,默认为Stretch。
2 Margin:决定了子控件距父元素边界的距离,注意在Margin设置和Alignment设置有关联,当需要设置四个方向的距离都不为0时,HorizontalAligment和VerticalAligment不进行设置。
1 <Button Margin="0,10,0,10">Button 1</Button> 2 <Button Margin="0,10,0,10">Button 2</Button> 3 <Button Margin="0,10,0,10">Button 3</Button>
3 Padding:填充,对于一些小控件往往需要增大其尺寸的大小,如button,Padding对于大小的改变和Margin非常类似,不同的是Margin可能导致控件越界,而Padding可以保证Margin始终在父控件的范围内。
1 Button bb = new Button(); 2 bb.Margin = new Thickness(20); 3 bb.Padding = new Thickness(10, 20, 30, 10); 4 this.MyGrid.Children.Add(bb);
Layout Containers
WPF的另一个重要部分是容器,WPF的引入的每一个Panels都是继承与Panel,我们能够定制自己想要的容器,WPF的基本容器如下:
PANEL
Panel是一个抽象类,其它Panel都是从该类继承而来,它有一些基本的属性:
1.Z-Index:决定了控件所在的层索引,Z—Index越高,控件所在的层数越高。
2.InternalChildren:基本元素集合,假如你使用的自定义控件,会需要该属性。
3.Background:指定背景颜色。
Custom Panel
建立一个自定义Panel,需要重写2个方法。MeasureOverride和ArrangeOverride。详情见http://go.microsoft.com/fwlink/?LinkID=159979 [^]
GRID
GRID是基本的布局,通过 RowDefination和ColumnDefination指定列和行。大小可以是
1.“Auto”:控件默认大小。
2.“*” : 比例大小,如果你想要两列的宽度是“2:1”,可以设置宽度为2*和1*。
3. Absolute:设置绝对大小。
从实践经验上来说,设置MinHeight和MaxWidth比较好
在上面
1 <Grid Grid.Row="1"> 2 <Grid.RowDefinitions> 3 <RowDefinition /> 4 <RowDefinition /> 5 <RowDefinition /> 6 </Grid.RowDefinitions> 7 <Grid.ColumnDefinitions> 8 <ColumnDefinition/> 9 <ColumnDefinition/> 10 <ColumnDefinition/> 11 </Grid.ColumnDefinitions> 12 <Border Background="BurlyWood" x:Name="brdElement"> 13 <TextBlock x:Name="tbElement" Text="Row 0, Column 0" 14 HorizontalAlignment="Center" VerticalAlignment="Center"/> 15 </Border> 16 </Grid>
样例中,建立一个3X3矩阵网格,使用TextBox动态的指定其位置
STACKPANEL
一个成堆状摆放panel的控件,子控件相互紧挨,没有重叠。用于顺序垂直或者水平排列子元素。通过orientation属性克制方向,默认是vertical。
stackPanel只有方向属性:vertical和Horizontal
<StackPanel x:Name="spMain" Orientation="Horizontal"> <Border Background="Brown" Padding="50"></Border> <Border Background="Green" Padding="50" /> </StackPanel>
Wrappanel
wrappanel和stackpanel类似,只是更加的灵活,当没有控件放置子元素时会自动将其放置在下一行或者下一列中,它特别适用于子元素个数不确定的情况。
1 <WrapPanel x:Name="wpMain" Grid.Row="1"> 2 <Border Background="Brown" Padding="30"/> 3 <Border Background="Green" Padding="30" /> 4 <Border Background="Brown" Padding="30" /> 5 <Border Background="Green" Padding="30" /> 6 </WrapPanel>
DockPanel
DockPanel广泛用于制定面板的布局,可以使子元素停靠在面板的某一条边上,然后拉伸元素以填满全部的高度和宽度。默认最后一个子元素将填满所有剩余空间。
1 <DockPanel> 2 <Border Background="Aqua" DockPanel.Dock="Top"> 3 <TextBlock Text="Dock:Top" /> 4 </Border> 5 <Border Background="Red" DockPanel.Dock="Bottom"> 6 <TextBlock Text="Dock:Bottom" /> 7 </Border> 8 <Border Background="Orange" DockPanel.Dock="Left"> 9 <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 10 Text="Dock:Left" /> 11 </Border> 12 <Border Background="Blue" DockPanel.Dock="Left"> 13 <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 14 Text="Dock:Left" /> 15 </Border> 16 <Border Background="Aqua" DockPanel.Dock="Bottom"> 17 <TextBlock Text="Dock:Top" /> 18 </Border> 19 <Border Background="Aquamarine" DockPanel.Dock="Top"> 20 <TextBlock Text="Dock:Top" /> 21 </Border> 22 <Border Background="BurlyWood" DockPanel.Dock="Right"> 23 <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 24 Text="Dock:Right" /> 25 </Border> 26 <Border Background="Coral" DockPanel.Dock="Right"> 27 <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 28 Text="Dock:Right" /> 29 </Border> 30 <Border Background="Cornsilk" > 31 <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 32 Text="Remaining Fill" /> 33 </Border> 34 </DockPanel>DockPanel
VirtualizingStackPanel
使用虚拟化技术的一种特殊面板,当数据绑定到元素时,虚拟化内容只有当显示在屏幕上时才会被生成,这样大大提高了控件性能。
1 <ListBox x:Name="lstElements" VirtualizingStackPanel.IsVirtualizing="True" 2 VirtualizingStackPanel.VirtualizationMode="Recycling" ItemsSource="{Binding}"/>
1 private void Window_Loaded(object sender, RoutedEventArgs e) 2 { 3 ObservableCollection<int> obs = new ObservableCollection<int>(); 4 Random rnd = new Random(1000); 5 for (int i = 0; i < 100000; i++) 6 obs.Add(rnd.Next()); 7 this.lstElements.DataContext = obs; 8 }
有100000个元素绑定到ListBox,使用virtualizingStackPanel,设置IsVirtualizing为true, 由于并不需要生成所有的数据,内容会一瞬间显示,如果IsVirtualizing为false,将花费很长的时间。
CANVAS
cavas是一种特殊的面板,它通过绝对坐标来指定元素的位置。当使用canvas时,可能出现相交的情况,使用ZIndex来指定元素的层数。
1 <Canvas> 2 <Border Canvas.Top="20" Canvas.Left="25" Background="Bisque" Width="30" 3 Height="25" /> 4 <Border Canvas.Top="20" Canvas.Right="25" Background="Green" Width="30" 5 Height="25" /> 6 <Border Canvas.Bottom="20" Canvas.Right="25" 7 Background="Black" Width="30" Height="25" /> 8 <Border Canvas.Bottom="20" Canvas.Left="25" Background="IndianRed" 9 Width="30" Height="25" /> 10 <Ellipse Fill="DarkGray" Canvas.Left="100" Canvas.Top="130" Width="100" 11 Height="80"></Ellipse> 12 <Ellipse Fill="DarkCyan" Canvas.Left="100" Canvas.Top="80" Width="100" 13 Height="80"></Ellipse> 14 <Ellipse Fill="DarkSalmon" Canvas.Left="140" Canvas.Top="100" Width="100" 15 Height="80" /> 16 </Canvas>
UniformGrid
uniformGrid是一种能够使网格中行列尺寸统一的面板。
1 <UniformGrid Columns="2" Rows="3"> 2 <Border Background="Red" /> 3 <Border Background="Green" /> 4 <Border Background="Blue" /> 5 <Border Background="Yellow" /> 6 <Border Background="DarkGoldenrod" /> 7 <Border Background="DarkKhaki" /> 8 </UniformGrid>
ScrollView
1 <ScrollViewer HorizontalScrollBarVisibility="Auto"> 2 <StackPanel VerticalAlignment="Top" HorizontalAlignment="Left"> 3 <TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is 4 enabled when it is necessary. Resize the window, making it larger 5 and smaller.</TextBlock> 6 <Rectangle Fill="Honeydew" Width="500" Height="500"></Rectangle> 7 </StackPanel> 8 </ScrollViewer>
GroupBox
1 <GroupBox Header="This goes to Header" Margin="50"> 2 <StackPanel> 3 <Button Content="First Element"/> 4 <Button Content="Second Element" /> 5 </StackPanel> 6 </GroupBox>
Expander
expander和grounpbox一样,不过是其内容可以隐藏。
1 <Expander Header="This goes to Header" Margin="50" IsExpanded="True" 2 ExpandDirection="Down"> 3 <StackPanel> 4 <Button Content="First Element"/> 5 <Button Content="Second Element" /> 6 </StackPanel> 7 </Expander>
ViewBox
一种可以使内容随着文本大小进行相应变动的控件。ViewBox的伸展有四个属性:
1.Fill:将文本按比例的扩充到控件全部。
2.None:没有伸展行为。
3.UniformToFill:统一的扩展元素到全屏,会导致长宽比发生变化。
4.Uniform:统一扩展元素。
1 <Viewbox Stretch="None" StretchDirection="Both" > 2 <Grid> 3 <TextBox Text="This is a content" FontWeight="Bold" FontSize="30" /> 4 </Grid> 5 </Viewbox>
Popup
一个特殊的控件有浮动窗口的效果。
1 <ToggleButton IsChecked="{Binding ElementName=pup, Path=IsOpen}" 2 Content="Open Popup" Margin="100" /> 3 <Popup Placement="Bottom" AllowsTransparency="True" 4 PopupAnimation="Fade" x:Name="pup" VerticalOffset="-100"> 5 <StackPanel> 6 <TextBlock Name="McTextBlock" Background="Black" Foreground="White" > 7 This is popup text 8 </TextBlock> 9 <Button Content="This is button on a Popup" /> 10 </StackPanel> 11 </Popup>
InkCanvas
WPF中一种强大的画板工具。
1 <StackPanel> 2 <InkCanvas Height="200" x:Name="icBox"> 3 </InkCanvas> 4 <RadioButton GroupName="mode" Checked="Pen_Checked" Content="Pen"/> 5 <RadioButton GroupName="mode" Checked="Erase_Checked" 6 Content="Eraser By Point" /> 7 <RadioButton GroupName="mode" Checked="EraseByStroke_Checked" 8 Content="Eraser By Stroke" /> 9 </StackPanel>
Transformation
变换是WPF引入的一种重要的特色。
变化有四种类型:
1.RotateTranfrom:旋转角度。
2.ScaleTransfrom:成倍的增加和减小控件的尺寸。
3.SkewTransfrom:倾斜一定的角度。
4.TranslateTransform:偏移指定的X,Y坐标。
1 <TextBlock FontWeight="Bold" FontSize="20" Text="This is Text" Margin="20"> 2 <TextBlock.RenderTransform> 3 <TransformGroup> 4 <RotateTransform Angle="20" /> 5 <SkewTransform AngleX="10" AngleY="10" /> 6 <TranslateTransform X="15" Y="19"/> 7 <ScaleTransform ScaleX="2" ScaleY="1" /> 8 </TransformGroup> 9 </TextBlock.RenderTransform> 10 </TextBlock>
文章来自似水无痕:http://www.cnblogs.com/keylei203/