在上文《WPF学习:1开始》中:简单介绍了WPF的架构和内部结构,接下来要讨论下写第一个WPF程序的基本知识,如何在window中放置控件,这对于想要开始学WPF的人都是非常简单的。
代码地址:http://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 ButtonButton>
效果是一样的,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 1Button> 2 <Button Margin="0,10,0,10">Button 2Button> 3 <Button Margin="0,10,0,10">Button 3Button>
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
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/