WPF XAML

作者: 李霖弢 | 来源:发表于2019-11-12 17:15 被阅读0次

XAML (Extensible Application Markup Language) 可扩展应用程序标记语言是一种基于 XML 的标记语言,以声明形式实现应用程序的外观。 通常用它创建窗口、对话框、页和用户控件,并填充控件、形状和图形,且自身即可实现动画效果(通过blend生成XAML)。
XAML中每个标签在运行时都会创建一个实例。 例如, Window 元素被转换为 Window 类的实例,该类的 Title 属性是 Title 特性的值。

命名空间 xmlns (XML Namespace)

xmlns[:自定义映射名] = "对应的命名空间"

例如想引入类库文件MyClass.dll中的命名空间ABC,则

xmlns:abc="clr-namespace:ABC;assembly=MyClass"
//效果类似于 using ABC = abc;

用于声明命名空间,如下<Window><Grid>均属于xmlns声明的默认命名空间,x:Class中的内容则属于xmlns:x声明的命名空间。其中配置的内容并非网址,而是一个XAML内置的一个对应关系,该内容对应了多个命名空间。
通过在AssemblyInfo.cs中添加[assembly:xmlnsDefinition("www.xxx.com","wpfLibrary")]也可以将自己的网址设置成一个命名空间的对应。

<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>
  </Grid>
</Window>

经过声明的命名空间下的类可以直接作为标签被使用

<abc:Tab>...</abc:Tab>

为XAML的对象属性赋值

  1. 使用字符串进行简单赋值
<Rectangle Grid.ColumnSpan="2" Fill="#F00" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100"/>
  1. 使用属性元素进行复杂赋值
    当属性是复杂对象时有优势
<Rectangle Grid.ColumnSpan="2" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100">
  <Rectangle.Fill>
    <SolidColorBrush Color="#F0F"/>
  </Rectangle.Fill>
</Rectangle>
  1. 标记扩展
    通过"{Binding XXX=XXX}"的方式将TextBox的属性依赖在SliderValue
<Slider Name="slider1"  Height="30" Width="100"/>
<TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}"  Height="30" TextWrapping="Wrap" Width="100"/>

或改用属性元素

<TextBox Text="{Binding ElementName=slider1,Path=Value,Mode=OneWay}"  Height="30" TextWrapping="Wrap" Width="100">
  <TextBox.Text>
    <Binding ElementName=slider1,Path=Value,Mode=OneWay>
  </TextBox.Text>
</TextBox>

X名称空间中的属性

x:Class

x:Class本身不是对象的成员,而是从x命名空间中拿出来硬贴上去的,且只能用于根节点
拥有x:Class的标签会自动解析为一个类名为x:Class的值的partial类(称为代码隐藏类),其嵌套的标签会被解析为其派生类,编译时会和.cs文件中的同名partial类合并。
拥有x:Class 的标签解析后的类自动拥有InitializeComponent方法,用于初始化窗体组件,将标记中定义的 UI 与代码隐藏类合并在一起。

通过Name属性在.cs中获取xaml中对应元素。

  • x:ClassModifier
    只能给有x:Class属性的标签添加,用于设置该类的访问权限
x:Name

通常可与Name互换。
当一个标签具有x:Name时,除了生成对应实例外还会为这个实例声明一个引用变量,变量名即x:Name的值

  • x:FieldModifier
    拥有x:Name的XAML标签实例,访问权限默认为internal。通过x:FieldModifier可以设置为public等。
x:Key 与 资源

为资源字典贴上用于检索的索引。

<Window xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <Window.Resources>
    <sys:String x:Key="myString">hello this is String</sys:String> 
  </Window.Resources>
  <TextBox Text="{StaticResource ResourceKey=myString}"/>
</Window>

在方法中也能获取资源

String myString = this.FindResource("myString") as String;
  • x:Shared
    若为true,每次通过x:Key获取的是同一个对象,否则为一个新的副本。默认为true

x名称空间中的标记扩展

x:Type,x:Null 与 Style

当需要指定某值为null时使用x:Null
如已经指定了所有ButtonStyle,但有一个不需采用该Style

<Window.Resources>
  <Style TargetType="{x:Type Button}">
    <Setter Property="Width" Value="50"></Setter>
  </Style>   
</Window.Resources>
<Button Style="{x:Null}"/>
x:Static

在XAML中直接使用类的static成员

<Button Content="{x:Static local:MainWindow.ButtonContent}"/>
...
public static string ButtonContent= "Click Me";
x:Array 与 ListBox

x:Array用于暴露一个指定类型的ArrayList/List实例

<ListBox>
  <ListBoxItem>1</ListBoxItem>
  <ListBoxItem>2</ListBoxItem>
</ListBox>

等价于

<ListBox Name="listbox"></ListBox>
...
listbox.ItemsSource = new List<string>(new []{"1","2"});

等价于

<ListBox>
  <ListBox.ItemsSource>
    <x:Array Type="sys:String">
      <sys:String>1</sys:String>
      <sys:String>2</sys:String>
    </x:Array>
  </ListBox.ItemsSource>
</ListBox>

控件与布局

有些控件的内容是一个集合,如StackPanel的内容属性是ChildrenListBox的内容属性是Items,当通过属性元素赋值时可以省略该内容属性的标签。

ContentControl基类

包括Window , ScrollViewer,各种ButtonCheckBox

  • 均具有内容属性Content
  • 内部最多只能包含一个元素
Button

表示 Windows 按钮控件,该按钮对 Click 事件作出反应

  • Click 绑定事件
  • ClickMode 触发方式
    • Hover => mouseover
    • Press => mousedown
    • Release => mouseup

ItemsControl 基类

包括Menu , ContextMenuComboBoxListBoxTabControl

  • 内容属性为ItemsItemsSource
  • 内容应为一个集合,且会自动被对应的条目容器进行包装
    ListBox的条目容器为ListBoxItem,因此以下两种写法等效
<ListBox>
  <Button Content="Click Me"/>
</ListBox>
<ListBox>
  <ListBoxItem>
    <Button Content="Click Me"/>
  </ListBoxItem>
</ListBox>
  • DisplayMemberPath 属性
    规定展示数组中每个对象的某个属性

TextBlock 和 TextBox

用于文本展示

  • TextBlock
    具有丰富的格式/排版控制
    内容属性为Inlines
  • TextBox
    支持用户自己编辑
    内容属性为Text

Panel基类与UI布局

内容属性均为Children

Grid 网格

类似Table,适用于行列对齐等
默认ColumnDefinition拥有Width="1*"RowDefinition拥有Height="1*"

  • 取值若为pxpx可省略
  • 若为Auto,则由其内容撑开,无内容则不占空间(可用Min-Width/Min-Height设置最小值)
  • 若为*,则由剩余空间按值分配(类似于flex的伸缩占比)
<Grid Name="myGrid">
  <Grid.ColumnDefinitions>
    <ColumnDefinition></ColumnDefinition>
    <ColumnDefinition></ColumnDefinition>
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="100px"></RowDefinition>
    <RowDefinition></RowDefinition>
    <RowDefinition Height="Auto"></RowDefinition>
  </Grid.RowDefinitions>
  <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1">hello</TextBlock>
</Grid>
...
myGrid.ColumnDefinitions.Add(new ColumnDefinition());
StackPanel

类似<div style="display:flex;"></div>

  • Orientation 元素排列方式
    Horizontal/Vertical
  • HorizontalAlignment 元素对齐方式
    Left/Center/Right/Stretch
  • VerticalAlignment 元素对齐方式
    Top/Center/Bottom/Stretch
Canvas

类似<div style="position:absolute;"></div>
其中的每个标签通过设置Canvas.LeftCanvas.Top属性来确定位置

DockPanel

内部元素通过DockPanel.Dock选择泊靠方向(类似浮动,但具有四个方向)

  • 最后一个子元素的DockPanel.Dock会被忽略,将尽量撑满整个DockPanel(可通过设置LastChildFill="false"禁用该功能)
<DockPanel>
    <TextBox BorderBrush="Blue" Height="100" DockPanel.Dock="Top">1</TextBox>
    <TextBox BorderBrush="Blue" Width="100" DockPanel.Dock="Left">2</TextBox>
    <TextBox BorderBrush="Blue">3</TextBox>
</DockPanel>
WrapPanel

流式布局,排满一行自动换行(类似子元素全为inline-block)
通过HorizontalAlignmentVerticalAlignment可以设置子元素整体在WrapPanel中的位置(不影响子元素间的相对位置关系)

<WrapPanel HorizontalAlignment="Right" VerticalAlignment="Center">
    <TextBox BorderBrush="Red" Width="100" Height="100">1</TextBox>
    <TextBox BorderBrush="Red" Width="100" Height="100">2</TextBox>
    <TextBox BorderBrush="Red" Width="100" Height="100">3</TextBox>
    <TextBox BorderBrush="Red" Width="100" Height="100">4</TextBox>
    <TextBox BorderBrush="Red" Width="100" Height="100">5</TextBox>
</WrapPanel>

动态修改XAML

Grid grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());

Button button = new Button() { Content="hello"};
Grid.SetColumn(button, 1);
Grid.SetRow(button, 1);

grid.Children.Add(button);
Content = grid;

事件处理器

一个XAML标签对应一个对象,标签的一部分属性对应对象的属性,另一部分则对应对象的事件。如:

<Button Name="button" Click="Button_Click"/>

约等于

private void Button_Click(object sender, RoutedEventArgs e){}
Button button = new Button();
button.click+=new RoutedEventHandler(Button_Click);

在事件中获取对象可以直接使用x:Name的值,也可以使用形参中的sender(即为事件的绑定者),配合.Children[0]等选取标签。

定位

  • Margin
    按照左上右下依次定义,默认为"0,0,0,0"
  • HorizontalAlignment
    水平定位,决定了Margin优先用左右哪个值,默认为"Left"
  • VerticalAlignment
    垂直定位,决定了Margin优先用上下哪个值,默认为"Top"

相关文章

  • Xaml GUI开发的当下.md

    XAML的诞生 Xaml是微软发布WPF时提出的GUI布局描述技术。 为何不用WPF 微软一贯的尿性,WPF已经不...

  • WPF自学系列 1XAML基础

    索引 XAML 标准 XAML 属性 XAML 事件 1.什么是XAML XAML是WPF语义化的一个特殊的XML...

  • WPF XAML

    XAML (Extensible Application Markup Language) 可扩展应用程序标记语言...

  • C# Template Codes

    Template namespace Form WPF Template Xaml Cite MVVMLight CEF

  • WPF生命周期

    App.xaml.cs wpf中Window的生命周期

  • ArcGIS Runtime SDK for WPF加载离线文件

    1.在WPF项目中通过nuget添加Esri.ArcGISRuntime.WPF 2.在XAML文件头添加命名空间...

  • XAML语法

    2.1 新建WPF项目 ### 略 2.2 剖析最简单的XAML代码 XAML是XML派生的 为了表示同类标签中的...

  • XAML基础

    一、概述 WPF前端采用XAML标记语言,XAML比以前的Winform控件模式益处在于前后端分离,丰富的UI 二...

  • 教程2:NoesisGUI和WPF / UWP之间的区别

    NoesisGUI和WPF / UWP之间的区别 本指南适用于来自XAML,Silverlight,Xamarin...

  • WPF之路-从XAML入手

    WPF新建好一个窗口后,会生成如下的XAML语句 同XML类似,XAML中最基本的语法元素就是标签、属性、内容 标...

网友评论

      本文标题:WPF XAML

      本文链接:https://www.haomeiwen.com/subject/lbsubctx.html