从这篇文章开始是对WPF中的界面如何布局做一个较简单的介绍,大家都知道:UI是做好一个软件很重要的因素,如果没有一个漂亮的UI,功能做的再好也无法吸引很多用户使用,而且没有漂亮的界面,那么普通用户会感觉这个软件没有多少使用价值。

一. 总体介绍

WPF的布局控件都在System.Windows.Controls.Panel这个基类下面,使用 WPF提供的各种控件在WPF应用程序中界面进行布局,同时对各种子控件(如按钮、文本框,下拉框等)进行排列组合。

Pane类的公共属性太多了。就简单介绍几个常见的属性如下表。

名称

说明

Cursor

获取或设置在鼠标指针位于此元素上时显示的光标。

DataContext

获取或设置元素参与数据绑定时的数据上下文。

Dispatcher

获取与此 DispatcherObject 关联的 Dispatcher。

FontFamily

获取或设置控件的字体系列。

FontSize

获取或设置字号。

FontWeight

获取或设置指定的字体的权重或粗细。

Foreground

获取或设置描述前景色的画笔。

HandlesScrolling

获取一个值控件是否支持滚动。

Height

获取或设置元素的建议高度。

HorizontalContentAlignment

获取或设置控件内容的水平对齐。

IsLoaded

获取一个值,该值指示是否已加载此元素以供呈现。

IsMouseOver

获取一个值,该值指示鼠标指针是否位于此元素(包括可视树上的子元素)上。这是一个依赖项属性。

IsTabStop

获取或设置一个值控制是否在选项卡上导航包含。

IsVisible

获取一个值,该值指示此元素在用户界面 (UI) 中是否可见。这是一个依赖项属性。

LayoutTransform

获取或设置在执行布局时应该应用于此元素的图形转换方式。

Margin

获取或设置元素的外边距。

Name

获取或设置元素的标识名称。 该名称提供一个引用,以便当 XAML 处理器在处理过程中构造标记元素之后,代码隐藏(如事件处理程序代码)可以对该元素进行引用。

Opacity

获取或设置当 UIElement 在用户界面 (UI) 中呈现时为其整体应用的不透明度因子。这是一个依赖项属性。

Padding

获取或设置控件中的空白。

RenderTransform

获取或设置影响此元素的呈现位置的转换信息。这是一个依赖项属性。

TabIndex

获取或设置使用 tab 键时,确定顺序接收焦点的元素的值,当用户将控件定位。

Tag

获取或设置任意对象值,该值可用于存储关于此元素的自定义信息。

ToolTip

获取或设置在用户界面 (UI) 中为此元素显示的工具提示对象。

TouchesCaptured

获取在此元素上捕获的所有触摸设备。

TouchesCapturedWithin

获取在此元素或其可视化树中的任何子元素上捕获的所有触摸设备。

VerticalContentAlignment

获取或设置控件内容的垂直对齐方式。

Visibility

获取或设置此元素的用户界面 (UI) 可见性。这是一个依赖项属性。

VisualOpacityMask

获取或设置 Brush 值,该值表示 Visual 的不透明蒙板。

Width

获取或设置元素的宽度。

一个Panel 的呈现就是测量和排列子控件,然后在屏幕上绘制它们。所以在布局的过程中会经过一系列的计算,那么子控件越多,执行的计算次数就越多,则性能就会变差。如果不需要进行复杂的布局,则尽量少用复杂布局控件(如 Grid和自定义复杂的Panel);如果能简单布局实现就尽量使用构造相对简单的布局(如 Canvas、UniformGrid等),这种布局可带来更好的性能。 如果有可能,我们应尽量避免调用 UpdateLayout方法。 
      每当Panel内的子控件改变其位置时,布局系统就可能触发一个新的处理过程。对此,了解哪些事件会调用布局系统就很重要,因为不必要的调用可能导致应用程序性能变差。 
       换句话说,布局是一个递归系统,实现在屏幕上对控件进行大小调整、定位和绘制,然后进行呈现。具体如下图,要实现控件0的布局,那么先要实现0的子控件 01,02...的布局,要实现01的布局,那么得实现01的子控件001,002...的布局,如此循环直到子控件的布局完成后,再完成父控件的布局, 最后递归回去直到递归结束,这样整个布局过程就完成了.

布局系统为Panel中的每个子控件完成两个处理过程:测量处理过程(Measure)和排列处理过程(Arrange)。每个子 Panel 均提供自己的 MeasureOverride 和 ArrangeOverride 方法,以实现自己特定的布局行为。

二. Canvas 

Canvas是最基本的面板,只是一个存储控件的容器,它不会自动调整内部元素的排列及大小,它仅支持用显式坐标定位控件,它也允许指定相对任何角的坐标,而不仅仅是左上角。可以使用Left、Top、Right、 Bottom附加属性在Canvas中定位控件。通过设置Left和Right属性的值表示元素最靠近的那条边,应该与Canvas左边缘或右边缘保持一个固定的距离,设置Top和Bottom的值也是类似的意思。实质上,你在选择每个控件停靠的角时,附加属性的值是作为外边距使用的。如果一个控件没有使 用任何附加属性,它会被放在Canvas的左上方(等同于设置Left和Top为0)。

Canvas的主要用途是用来画图。Canvas默认不会自动裁减超过自身范围的内容,即溢出的内容会显示在Canvas外面,这是因为默认 ClipToBounds=”False”;我们可以通过设置ClipToBounds=”True”来裁剪多出的内容。

接下来我们来看两个实例,第一个实例使用XAML代码实现:

<Window x:Class="WpfApp1.WindowCanvas"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="WindowCanvas" Height="400" Width="500">

    <Grid>

        <Canvas Margin="0,0,0,0" Background="White">

            <Rectangle Fill="Blue" 

                Stroke="Azure" 

                Width="250" 

                Height="200" 

                Canvas.Left="210" Canvas.Top="101"/>

            <Ellipse Fill="Red" 

                Stroke="Green" 

                Width="250" Height="100" 

                Panel.ZIndex="1" 

                Canvas.Left="65" Canvas.Top="45"/>

        </Canvas>

        <Canvas>

            <Button Name="btnByCode" Click="btnByCode_Click">后台代码实现</Button>

        </Canvas>

    </Grid>

</Window>

实例后的效果如下图。

第二个实例,我们使用后台代码来实现。我使用C#来实现

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Shapes;

namespace WpfApp1

{

    /// <summary>

    /// WindowCanvas.xaml 的交互逻辑

    /// </summary>

    public partial class WindowCanvas : Window

    {

        public WindowCanvas()

        {

            InitializeComponent();

        }

        public void DisplayCanvas()

        {

            Canvas canv = new Canvas();

            //把canv添加为窗体的子控件

            this.Content = canv;

            canv.Margin = new Thickness(, , , );

            canv.Background = new SolidColorBrush(Colors.White);

            //Rectangle

            Rectangle r = new Rectangle();

            r.Fill = new SolidColorBrush(Colors.Red);

            r.Stroke = new SolidColorBrush(Colors.Red);

            r.Width = ;

            r.Height = ;

            r.SetValue(Canvas.LeftProperty, (double));

            r.SetValue(Canvas.TopProperty, (double));

            canv.Children.Add(r);

            //Ellipse

            Ellipse el = new Ellipse();

            el.Fill = new SolidColorBrush(Colors.Blue);

            el.Stroke = new SolidColorBrush(Colors.Blue);

            el.Width = ;

            el.Height = ;

            el.SetValue(Canvas.ZIndexProperty, );

            el.SetValue(Canvas.LeftProperty, (double));

            el.SetValue(Canvas.TopProperty, (double));

            canv.Children.Add(el);

        }

        private void btnByCode_Click(object sender, RoutedEventArgs e)

        {

            DisplayCanvas();

        }

    }

}

实现后的效果如下图。

最后 要说明一点Canvas内的子控件不能使用两个以上的Canvas附加属性,如果同时设置Canvas.Left和Canvas.Right属性,那么后者将会被忽略。

WPF入门教程系列六——布局介绍与Canvas(一)的更多相关文章

  1. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  2. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  3. WPF入门教程系列八——布局之Grid与UniformGrid(三)

    五. Grid Grid顾名思义就是“网格”,它的子控件被放在一个一个实现定义好的小格子里面,整齐配列. Grid和其他各个Panel比较起来,功能最多也最为复杂.要使用Grid,首先要向RowDef ...

  4. WPF入门教程系列四——Dispatcher介绍

    一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以 ...

  5. WPF入门教程系列九——布局之DockPanel与ViewBox(四)

    七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中.停靠面板其实就是在WinForm类似于Dock属性的元 ...

  6. WPF入门教程系列十——布局之Border与ViewBox(五)

    九. Border Border 是一个装饰的控件,此控件绘制边框及背景,在 Border 中只能有一个子控件,若要显示多个子控件,需要将一个附加的 Panel 控件放置在父 Border 中.然后可 ...

  7. WPF入门教程系列七——布局之WrapPanel与StackPanel(二)

    三. WrapPanel WrapPanel布局面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够是就会自动调整进行换行,后续排序按照从上至下或从右至左的顺序进行. Orientation— ...

  8. WPF入门教程系列五——Window 介绍

    一.窗体类基本概念 对于WPF应用程序,在Visual Studio和Expression Blend中,自定义的窗体均继承System.Windows.Window类.用户通过窗口与 Windows ...

  9. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

随机推荐

  1. CSS 自定义字体

    移动端如何兼容UI给的字体 [toc] 移动端的默认字体 IOS 默认中文字体是Heiti SC 默认英文字体是Helvetica 默认数字字体是HelveticaNeue Android 默认中文字 ...

  2. ArcGIS10.1 api for Flex开发用于ArcGIS 9.3时QueryTask 'Error #2032'错误的解决方案

    因客户GIS软件需求,将应用降级到低版本ArcGIS9.3,不仅数据有些样式.配色.字符有些问题,API也要相应“降级”,解决如下: 利用9.3+flex做QueryTask时候出现了[RPC Fau ...

  3. webpack入门指南(转载)

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  4. nginx简易安装

    yum -y install perl-ExtUtils-Embed ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx ...

  5. out与ref的区别

    out与ref的区别  前者传参时不必初始化,后者需要初始化 int a,b; public void fName(out int a,out int b); fName(out a , out b) ...

  6. debian下使用gitosis+gitweb搭建SSH认证的git服务器

    搭建完成Git服务器后,需要使用两台机器进行测试,一台机器作为服务器端server,一台服务器作为客户端client.整个系统,需要三个计算机账户,这里假设server端的账户名为git,client ...

  7. datax+hadoop2.X兼容性调试

    以hdfsreader到hdfswriter为例进行说明: 1.datax的任务配置文件里需要指明使用的hadoop的配置文件,在datax+hadoop1.X的时候,可以直接使用hadoop1.X/ ...

  8. 关于“windows无法自动将ip协议栈绑定到网络适配器”问题导致不能连上网的解决办法

    问题出现的原因:这个问题的直接表象并不是显示给用户这个问题,而是提示无线网络驱动可能有问题或者以太网驱动可能有问题,但只要用户查看”详细信息“,就会得到标题这个问题,而出现这个问题的本质并不是驱动问题 ...

  9. Junit3与Junit4的区别

    Junit4最大的亮点就是引入了注解(annotation),通过解析注解就可以为测试提供相应的信息,抛弃junit3使用命名约束以及反射机制的方法. /** * 被测试类 */ package co ...

  10. Apache HTTP Server 2.2.26 发布

    Apache遗留产品线2.2.26发布.2013-11-13 之前的版本是2013-07-02的2.2.25 同样先在开发目录下放出下载,然后放到正式目录下.修正了大量的Bug.目前的稳定版2.4系列 ...