zoukankan      html  css  js  c++  java
  • WPF Control Layout

    Link:http://www.aspfree.com/c/a/Windows-Scripting/WPF-Control-Layout/

    Note that the examples in this article are all created as part of browser-hosted applications for the purpose of taking simple screenshots. Furthermore, the dimensions of the pages may be modified in order to make the result small and visually appealing, or to show off a particular feature (e.g. wrapping with the WrapPanel).

    Canvas

    We'll start by looking at the Canvas control. This control is a bit unique in that it doesn't arrange its children controls in any way. Rather, each child can be positioned individually using an absolute positioning system. So, in one light,Canvas can be seen as primitive, and in another light, it can be seen as flexible, since you're not confined to a particular layout scheme when using it. The Canvas control, then, can be used to create some fancy applications.

    Here's an example of an interesting layout that can be created with Canvas:



    You can arrange controls by specifying their Canvas.Top,Canvas.Left,Canvas.Bottom, andCanvas.Right attributes, which map to positions on the canvas.Canvas.Top specifies the distance from the top of theCanvas,Canvas.Left specifies the distance from the left side of theCanvas,Canvas.Bottom specifies the distance from the bottom of theCanvas, andCanvas.Right specifies the distance from the right side of the canvas. So, a control with aLeft value of 10 and aTop value of 20 would have its top left corner 10 pixels from the left side of theCanvas and 20 pixels from the top of the canvas. The above layout, then, can be created like this:


    <Canvas>

     <Button Canvas.Left="10" Canvas.Top="10"

     Content="Button 1" />

     <Button Canvas.Left="60" Canvas.Top="60"

     Content="Button 2" />

     <Button Canvas.Left="110" Canvas.Top="110"

     Content="Button 3" />

     <Button Canvas.Left="60" Canvas.Top="160"

     Content="Button 4" />

     <Button Canvas.Left="10" Canvas.Top="210"

     Content="Button 5" />

    </Canvas>


    Above, Canvas.Left andCanvas.Top are specified. However, let's useCanvas.Right andCanvas.Bottom to create a mirror image:



    <Canvas>

     <Button Canvas.Right="10" Canvas.Bottom="210"

     Content="Button 1" />

     <Button Canvas.Right="60" Canvas.Bottom="160"

     Content="Button 2" />

     <Button Canvas.Right="110" Canvas.Bottom="110"

     Content="Button 3" />

     <Button Canvas.Right="60" Canvas.Bottom="60"

     Content="Button 4" />

     <Button Canvas.Right="10" Canvas.Bottom="10"

     Content="Button 5" />

    </Canvas>

    StackPanel

    Perhaps the simplest layout involves placing controls in a vertical or horizontal line. This can also be seen as “stacking” controls—putting one on top of another, or beside another as it's added to the page. This type of layout is possible through aStackPanel. Controls placed within aStackPanel tag will display stacked in the order that you create them. TheStackPanel features anOrientation property that can be set to eitherVertical orHorizontal. A vertical orientation can produce something like this:



    And a horizontal orientation can produce something like this:



    The two examples above use almost the exact same code. The only difference is that theOrientation properties are set to different values.

    The first example can be reproduced with the following XAML:


    <StackPanel Orientation="Vertical">

     <Button Content="Button 1" />

     <Button Content="Button 2" />

     <Button Content="Button 3" />

     <Button Content="Button 4" />

    </StackPanel>


    Above, we explicitly set the Orientation property. However, when stacking things vertically, this actually isn't necessary, since the default value is Vertical. We could have achieved the same results by leaving it out altogether:


    <StackPanel>

     ...

    </StackPanel>


    The second example can be reproduced simply by changing the value of Orientation:


    <StackPanel Orientation="Horizontal">

     <Button Content="Button 1" />

     <Button Content="Button 2" />

     <Button Content="Button 3" />

     <Button Content="Button 4" />

    </StackPanel>


    It's also possible to put one StackPanel within another, if necessary. Using this approach, something like this could be achieved:



    <StackPanel Orientation="Vertical">

     <Button Content="Button 1" />

     <StackPanel Orientation="Horizontal">

     <Button Content="Button 2" />

     <Button Content="Button 3" />

     <Button Content="Button 4" />

     </StackPanel>

    </StackPanel>


    However, for more advanced layouts requiring distinct rows and columns, the Grid layout element, which will be covered later, is a much better choice.

    The default value for HorizontalAlignment andVeritcalAlignment for controls within aStackPanel isStretch. This can produce some odd results (such as the example with a horizontal orientation). So, in some situations, it may be best to change this to a more natural look:



    <StackPanel Orientation="Horizontal">

     <Button Content="Button 1" VerticalAlignment="Center" />

     <Button Content="Button 2" VerticalAlignment="Center" />

     <Button Content="Button 3" VerticalAlignment="Center" />

     <Button Content="Button 4" VerticalAlignment="Center" />

    </StackPanel>


    A better way to do this would be to create a style within the StackPanel:
    <StackPanel.Resources>
    <Style TargetType="{x:Type Button}">
    <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
    </StackPanel.Resources>

    WrapPanel

    WrapPanel is similar toStackPanel. The difference is that, whereasStackPanel puts each new control in a new row or column,WrapPanel keeps adding controls in the desired direction until there is no more space. Then, it puts the next control into a new row or column, “wrapping” it similar to the way text may be wrapped. Also, like StackPanel,WrapPanel has anOrientation property, except it defaults toHorizontal.

    A WrapPanel confined to a width of 300 pixels will render eight buttons like this:



    <WrapPanel>

     <Button Content="Button 1" />

     <Button Content="Button 2" />

     <Button Content="Button 3" />

     <Button Content="Button 4" />

     <Button Content="Button 5" />

     <Button Content="Button 6" />

     <Button Content="Button 7" />

     <Button Content="Button 8" />

    </WrapPanel>


    The above WrapPanel has a horizontal orientation (the default, remember), but switching theOrientation property toVertical and confining theWrapPanel to a height of 100 pixels would render the same eight buttons differently:



    <WrapPanel Orientation="Vertical">

     ...

    </WrapPanel>

    DockPanel

    Next, we'll look at the DockPanel control.DockPanel is a bit odd in that its child controls are arranged relative to one another. That is, controls may be placed to the top, bottom, left, and right of other controls. This relative arrangement is governed by theDockPanel.Dock attribute. For example, if one control has itsDockPanel.Dock attribute set to Top in the XAML, then it will be positioned above the control that follows it. Two buttons in this situation would look something like this:



    And the corresponding XAML would look like this:


    <DockPanel>

     <Button DockPanel.Dock="Top" Content="Button 1" />

     <Button Content="Button 2" />

    </DockPanel>


    Note that a DockPanel will use upall of the available space. In the above picture, theDockPanel is confined to aPage with a width of 200 pixels and a height of 100 pixels. Both buttons are stretched horizontally to take up the entire available width, and the second button is stretched vertically to take up the rest of the available height. You can, however, get rid of the default stretch behavior in the same way as withStackPanel:


    <DockPanel>

     <Button DockPanel.Dock="Top" Content="Button 1"

     HorizontalAlignment="Center" />

     <Button Content="Button 2" HorizontalAlignment="Center"

     VerticalAlignment="Center" />

    </DockPanel>


    More controls can be added to the application to produce something more complex:



    <DockPanel>

     <Button DockPanel.Dock="Top" Content="Button 1" />

     <Button DockPanel.Dock="Left" Content="Button 2" />

     <Button DockPanel.Dock="Bottom" Content="Button 3" />

     <Button Content="Button 4" />

    </DockPanel>

    Grid

    The final layout control we'll be looking at is theGrid control. TheGrid control behaves exactly as its name implies: it consists of a grid with rows and columns defined by the user, and each control occupies a cell within the grid. Each control has a row and a column, and a control can also have a row span and a column span in order to occupy multiple cells.

    Below, four buttons are arranged in aGrid with two rows and two columns:



    There are two steps involved in creating aGrid of controls. First, the rows and columns must be defined. Then, the controls are created. Controls can be placed in an individual cell using Grid.Row andGrid.Column attributes. The controls and layout in the above picture can be produced with the following XAML, which shows both steps necessary to create a functional Grid:


    <Grid>

     <Grid.RowDefinitions>

     <RowDefinition />

     <RowDefinition />

     </Grid.RowDefinitions>

     <Grid.ColumnDefinitions>

     <ColumnDefinition />

     <ColumnDefinition />

     </Grid.ColumnDefinitions>

     

     <Button Grid.Row="0" Grid.Column="0" Content="Button 1" />

     <Button Grid.Row="0" Grid.Column="1" Content="Button 2" />

     <Button Grid.Row="1" Grid.Column="0" Content="Button 3" />

     <Button Grid.Row="1" Grid.Column="1" Content="Button 4" />

    </Grid>


    Note that in the above example, theGrid is stretched (by default) to fit the entirePage, and the controls are stretched to fit the entire cell of the Grid. This can, of course, be changed with theHorizontalAlignment andVerticalAlignment process, but I won't bother spending time on that, since you should know the process by now. Also, the first row is the zero row, and the first column is the zero column.

    Notice how the RowDefinition andColumnDefinition attributes have no attributes. Ordinarly, however, the rows are given a height, and the columns are given a width. Below, we make rows 30 pixels high and columns 100 pixels wide:



    <Grid>

     <Grid.RowDefinitions>

     <RowDefinition Height="30" />

     <RowDefinition />

     </Grid.RowDefinitions>

     <Grid.ColumnDefinitions>

     <ColumnDefinition Width="100" />

     <ColumnDefinition Width="100" />

     </Grid.ColumnDefinitions>

     

     <Button Grid.Row="0" Grid.Column="0" Content="Button 1" />

     <Button Grid.Row="0" Grid.Column="1" Content="Button 2" />

     <Button Grid.Row="1" Grid.Column="0" Content="Button 3" />

     <Button Grid.Row="1" Grid.Column="1" Content="Button 4" />

    </Grid>


    Instead of providing a specific measurement, however, a control can be made to take up all of the available space (or divide it up among other controls) with this setting:



    <Grid>

     <Grid.RowDefinitions>

     <RowDefinition Height="30" />

     <RowDefinition Height="30" />

     </Grid.RowDefinitions>

     <Grid.ColumnDefinitions>

     <ColumnDefinition Width="50" />

     <ColumnDefinition Width="*" />

     </Grid.ColumnDefinitions>

     

     <Button Grid.Row="0" Grid.Column="0" Content="Button 1" />

     <Button Grid.Row="0" Grid.Column="1" Content="Button 2" />

     <Button Grid.Row="1" Grid.Column="0" Content="Button 3" />

     <Button Grid.Row="1" Grid.Column="1" Content="Button 4" />

    </Grid>


    As mentioned earlier, a control can also span multiple rows:



    <Grid>

     <Grid.RowDefinitions>

     <RowDefinition Height="30" />

     <RowDefinition Height="30" />

     </Grid.RowDefinitions>

     <Grid.ColumnDefinitions>

     <ColumnDefinition Width="50" />

     <ColumnDefinition Width="50" />

     </Grid.ColumnDefinitions>

     

     <Button Grid.Row="0" Grid.RowSpan="2" Grid.Column="0"

     Content="Button 1" />

     <Button Grid.Row="0" Grid.Column="1" Content="Button 2" />

     <Button Grid.Row="1" Grid.Column="1" Content="Button 3" />

    </Grid>


    A control can also span multiple columns (the row and column definitions are the same for this example):



    <Grid>

     ...

     

     <Button Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"

     Content="Button 1" />

     <Button Grid.Row="1" Grid.Column="0" Content="Button 2" />

     <Button Grid.Row="1" Grid.Column="1" Content="Button 3" />

    </Grid>


    Now you've learned about five layout elements in WPF:Canvas,StackPanel,WrapPanel,DockPanel, andGrid. Using one of these five elements, or a combination of several of them, you can achieve some complex control arrangements that will fit any application. The only thing left is to decide what elements to apply, but I'll leave that up to you.


    作者:Angelo Lee
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    170516、ActiveMQ 的安装与使用(单节点)
    170515、mybatis批量操作
    170512、java日志文件log4j.properties配置详解
    170511、Spring IOC和AOP 原理彻底搞懂
    170510、数据库默认隔离级别
    170509、文本编辑器编写的shell脚本在linux下无法执行的解决方法
    170508、忘记jenkins密码或者修改jenkins密码
    170505、MySQL的or/in/union与索引优化
    170504、MongoDB和MySQL对比(译)
    Jenkins Android 打包
  • 原文地址:https://www.cnblogs.com/yefengmeander/p/2887617.html
Copyright © 2011-2022 走看看