WPF XAML

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"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容