WPF自学笔记

WPF使用哪几种元素作为顶级元素:

1. Window元素

2. Page元素(与Window元素类似,用于可导航的应用程序)

3. Application元素(定义应用程序资源和启动设置)

PS:在一个WPF应用程序中只能有一个顶级元素

1 <Window x:Class="WpfApplication2.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525">
5     <Grid>
6         
7     </Grid>
8 </Window>

Class是类

xmlnsXML Namespaces的缩写,中文名称是XML(标准通用标记语言的子集)命名空间

Xmlns[:可选的映射前缀]=“名称空间”

为元素命名:(以Grid元素为例)

例一:

1 <Window x:Class="WpfApplication2.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525">
5     <Grid Name="grid1">
6         
7     </Grid>
8 </Window>

例二:

1 <Window x:Class="WpfApplication2.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525">
5     <Grid>
6         <Grid.Name>grid1</Grid.Name>
7     </Grid>
8 </Window>

以上两个例子等效

以上是UI层面的代码

逻辑代码层面调用上面的Grid元素的Name属性为例:

下面代码执行后会把窗体的标题改为Grid元素的名字属性(试了<Grid.Name>grid1</Grid.Name>无效)

UI层代码

1 <Window x:Class="WpfApplication2.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
5     <Grid Name="grid1">
6     </Grid>
7 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace WpfApplication2
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27 
28         private void Window_Loaded(object sender, RoutedEventArgs e)
29         {
30             this.Title = this.grid1.Name;
31         }
32     }
33 }

 简单元素例子:

新建一个button按钮和textbox文本框,实现功能:点击button按钮弹出对话框打印textbox文本框的内容

UI层:

1 <Window x:Class="WpfApplication2.MainWindow"
2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4         Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
5     <Grid Name="grid1">
6         <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="91,130,0,0" Click="Button_Click_1"/>
7         <TextBox HorizontalAlignment="Left" Height="23" Margin="91,61,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Name="txtShow"/>
8     </Grid>
9 </Window>

逻辑层:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace WpfApplication2
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27 
28         private void Window_Loaded(object sender, RoutedEventArgs e)
29         {
30             this.Title = this.grid1.Name;
31         }
32 
33         private void Button_Click_1(object sender, RoutedEventArgs e)
34         {
35             MessageBox.Show(txtShow.Text);
36         }
37     }
38 }

 背景颜色渐变例子:

UI层:(只需修改UI层,逻辑层不变)

 1 <Window x:Class="WpfApplication2.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
 5     <Grid Name="grid1">
 6         <Grid.Background>
 7             <LinearGradientBrush>
 8                 <LinearGradientBrush.GradientStops>
 9                     <GradientStop Offset="0.00" Color="Red"/>
10                     <GradientStop Offset="0.50" Color="Green"/>
11                     <GradientStop Offset="1.00" Color="Blue"/>
12                 </LinearGradientBrush.GradientStops>
13             </LinearGradientBrush>
14         </Grid.Background>
15         <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="91,130,0,0" Click="Button_Click_1"/>
16         <TextBox HorizontalAlignment="Left" Height="23" Margin="91,61,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Name="txtShow"/>
17     </Grid>
18 </Window>

运行效果:

用代码来创建WPF窗体:

新建个WPF的项目,把项目中的XAML文件都排除了,然后添加两个类,如图:

Class1类代码如下:

 1 using System.Windows;
 2 using System.Windows.Controls;
 3 using System.Windows.Markup;
 4 
 5 
 6 namespace WPF基础
 7 {
 8     class Class1:Window
 9     {
10         private Button button1;
11         public Class1()
12         {
13             InitializeComponent();
14         }
15         private void InitializeComponent()
16         {
17             //设置窗体
18             this.Width = 285;
19             this.Height = 250;
20             this.Left = this.Top = 100;
21             this.Title = "代码创建的新窗体";
22             //创建停靠面板对象
23             DockPanel panel = new DockPanel();
24             //创建按钮对象
25             button1 = new Button();
26             button1.Content = "请点击";
27             button1.Margin = new Thickness(30);
28             button1.Click += button1_Click;//注册按钮事件
29 
30             IAddChild container = panel;//不明白IAddChild作用是什么
31             container.AddChild(button1);//添加子对象
32 
33             container = this;
34             container.AddChild(panel);
35         }
36         private void button1_Click(object sender,RoutedEventArgs e)
37         {
38             button1.Content = "已点击";
39         }
40     }
41 }

Class2代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 
 7 namespace WPF基础
 8 {
 9     class Class2:Application
10     {
11         [STAThread()]//单线程的东西,不明白(指示应用程序的 COM 线程模型是单线程单元 (STA)。)
12         static void Main()
13         {
14             Class2 app = new Class2();
15             app.MainWindow = new Class1();
16             app.MainWindow.ShowDialog();//模态化打开窗体
17         }
18     }
19 }

设置项目属性:(启动对象设置为Class2类)

使用代码和未经编译的标记XAML创建WPF应用程序:

新建一个文本,输入以下代码,并把文本文件改为xaml后缀格式的xaml文件:(文件名:Window2.xaml)

1 <DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2 <Button Name="button1" Margin="60">Please click me.</Button>
3 </DockPanel>

以上新建的文件放入将会新建的WPF程序的根目录:

一般在文件夹下

新建WPF窗体(窗体名:Window2)

窗体逻辑层代码如下:

 1 using System.Windows;
 2 using System.Windows.Controls;
 3 using System.IO;
 4 using System.Windows.Markup;
 5 
 6 namespace WPF基础
 7 {
 8     /// <summary>
 9     /// Window1.xaml 的交互逻辑
10     /// </summary>
11     public partial class Window1 : Window
12     {
13         private Button myButton;
14         public Window1()
15         {
16             InitializeComponent();
17         }
18         public Window1(string xmalFile)
19         { 
20             //设置窗体
21             this.Width = this.Height = 285;
22             this.Left = this.Top = 100;
23             this.Title = "动态加载XAML文档";
24 
25             //从外部的XAML文件里获取XAML内容
26             DependencyObject ddo;
27             using (FileStream fs = new FileStream(xmalFile, FileMode.Open))
28             {
29                 ddo = (DependencyObject)XamlReader.Load(fs);
30             }
31             this.Content = ddo;
32             myButton = (Button)LogicalTreeHelper.FindLogicalNode(ddo, "button1");
33             myButton.Click += myButton_Click;
34         }
35         private void myButton_Click(object sender, RoutedEventArgs e)
36         {
37             myButton.Content = "已点击";
38         }
39     }
40 }

修改上一个例子的启动类(Class2),代码如下:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Windows;
 6 
 7 namespace WPF基础
 8 {
 9     class Class2:Application
10     {
11         [STAThread()]//单线程的东西,不明白(指示应用程序的 COM 线程模型是单线程单元 (STA)。)
12         static void Main()
13         {
14             //设置启动Class1类的代码构建WPF窗体
15             //Class2 app = new Class2();
16             //app.MainWindow = new Class1();
17             //app.MainWindow.ShowDialog();//模态化打开窗体
18 
19             //设置启动WPF窗体Window1
20             Class2 app = new Class2();
21             app.MainWindow = new Window1("Window2.xaml");
22             app.MainWindow.ShowDialog();
23         }
24     }
25 }

运行效果:

附上源代码文件:

WPF基础.rar

使用StackPanel面板进行简单布局:

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Border Background="red" BorderThickness="20" Padding="25" CornerRadius="30">
 6         <!-- Background="red" 背景颜色=“红色” BorderThickness="20" 边框粗细=“20像素” Padding="25" 容器边缘到内部控件的距离=“25像素” 也可以Padding="10,0,5,0"这样填  CornerRadius="30" 设置边框圆角-->
 7         <StackPanel Name="stackPanel1" Orientation="Vertical">
 8             <!-- Orientation="Horizontal" 方向属性=水平方向,Vertical垂直方向-->
 9             <Label Content="Label"/>
10             <Button Content="Button1" HorizontalAlignment="Left"/>
11             <!-- HorizontalAlignment="Left" 水平方向=左-->
12             <Button Content="Button2" VerticalAlignment="Center"/>
13             <!-- VerticalAlignment="Center" 垂直方向=居中-->
14             <Button Content="Button3" Margin="0,0,10,0" MinWidth="20" MaxWidth="200"/>
15             <!-- Margin="0,0,10,0" 边距=“左,顶,右,底”MinWidth="20" 最小宽度=“20像素” MaxWidth="200" 最大宽度=“200像素”-->
16             <Button Content="Button4"/>
17         </StackPanel>
18     </Border>
19 </Window>

运行效果:

WrapPanel面板设置:

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

 Orientation——根据内容自动换行。当 Horizontal选项看上去类似于Windows资源管理器的缩略图视图:元素是从左向右排列的,然后自上至下自动换行。Vertical 选项看上去类似于Windows资源管理器的列表视图:元素是从上向下排列的,然后从左至右自动换行。

   ItemHeight——所有子元素都一致的高度。每个子元素填充高度的方式取决于它的VerticalAlignment属性、Height属性等。任何比ItemHeight高的元素都将被截断。

   ItemWidth——所有子元素都一致的宽度。每个子元素填充高度的方式取决于它的VerticalAlignment属性、Width属性等。任何比ItemWidth高的元素都将被截断。

DockPanel面板设置:

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Border Background="red" BorderThickness="20" Padding="25" CornerRadius="30">
 6         <!-- Background="red" 背景颜色=“红色” BorderThickness="20" 边框粗细=“20像素” Padding="25" 容器边缘到内部控件的距离=“25像素” 也可以Padding="10,0,5,0"这样填  CornerRadius="30" 设置边框圆角-->
 7         <DockPanel >
 8             <Button Content="left" DockPanel.Dock="Left"/>
 9             <Button Content="top" DockPanel.Dock="Top"/>
10             <Button Content="bottom" DockPanel.Dock="Bottom"/>
11             <Button Content="right" DockPanel.Dock="Right"/>
12             <Button Content="Btn4" Height="25"/>
13             <Button Content="Btn5" Width="50"/>
14         </DockPanel>
15     </Border>
16 </Window>

运行效果:

如果DockPanel设置了LastChildFill属性为True就是把最后一个控件元素填充剩下的空间(<DockPanel LastChildFill="True">)

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Border Background="red" BorderThickness="20" Padding="25" CornerRadius="30">
 6         <!-- Background="red" 背景颜色=“红色” BorderThickness="20" 边框粗细=“20像素” Padding="25" 容器边缘到内部控件的距离=“25像素” 也可以Padding="10,0,5,0"这样填  CornerRadius="30" 设置边框圆角-->
 7         <DockPanel LastChildFill="True">
 8             <Button Content="left" DockPanel.Dock="Left"/>
 9             <Button Content="top" DockPanel.Dock="Top"/>
10             <Button Content="bottom" DockPanel.Dock="Bottom"/>
11             <Button Content="right" DockPanel.Dock="Right"/>
12             <Button Content="Btn4" Height="25"/>
13             <Button Content="Btn5" />
14         </DockPanel>
15     </Border>
16 </Window>

运行效果:

 利用以上知识嵌套:

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5         <DockPanel>
 6             <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
 7             <!-- DockPanel.Dock="Bottom" 设置在DockPanel面板中的位置 Orientation="Horizontal" 方向属性=水平方向 HorizontalAlignment="Right" 水平方向=右-->
 8                 <Button Content="OK" Margin="10,10,2,10" Padding="3"/>
 9                 <Button Content="Cancel" Margin="2,10,10,10" Padding="3"/>
10             </StackPanel>
11         <TextBox DockPanel.Dock="Bottom">这是一个文本框</TextBox>
12     </DockPanel>
13 </Window>

运行效果:

Grid面板使用:

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Grid ShowGridLines="False" UseLayoutRounding="True">
 6         <!-- ShowGridLines="False" 显示网格=“否”, UseLayoutRounding="True" 边缘清晰=“是”-->
 7         <Grid.RowDefinitions>
 8             <!-- Grid.RowDefinitions 设置行-->
 9             <RowDefinition></RowDefinition>
10             <!-- RowDefinition 新增一行-->
11             <RowDefinition></RowDefinition>
12         </Grid.RowDefinitions>
13         <Grid.ColumnDefinitions>
14             <!-- Grid.ColumnDefinitions 设置列-->
15             <ColumnDefinition Width="*" MinWidth="50"></ColumnDefinition>
16             <!-- ColumnDefinitio 新增一列 Width="*" 设定宽度标准*,以后出现的*就是相等标准,2*就是两倍标准,以此类推,MinWidth="50" 最小宽度=“50像素”-->
17             <ColumnDefinition Width="Auto"></ColumnDefinition>
18             <!-- Width="Auto" 宽度=“自动”-->
19             <ColumnDefinition Width="2*" MinWidth="50"></ColumnDefinition>
20             <ColumnDefinition Width="4*"></ColumnDefinition>
21         </Grid.ColumnDefinitions>
22         <Button Content="LeftTop" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="3"/>
23         <!-- Grid.Row="0" 所在行=“0”,Grid.Column="0" 所在列=“0”,Grid.ColumnSpan="2" 占用列空间=“2”, Margin="3" 控件边缘到字体的长度=“3”-->
24         <Button Content="CenterTop" Grid.Row="0" Grid.Column="2" Margin="3"/>
25         <Button Content="RightBottom" Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Margin="3"/>
26         <GridSplitter Grid.Column="1" Width="3" Grid.RowSpan="2" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
27         <!-- GridSplitter控件可拖动改变该控件左右两边的列的大小,VerticalAlignment="Stretch" 垂直方向设置=“从顶到底”,HorizontalAlignment="Center" 水平方向设置=“居中”-->
28     </Grid>
29 </Window>

运行效果:

 关于Grid面板的共享尺寸组属性(SharedSizeGroup):

设置列ColumnDefinition 属性中的 SharedSizeGroup ,SharedSizeGroup的值相同时,可以控制一个Grid中的列和另外一个Gird中的某一列的宽度相同。
还有一个要注意的是 顶级Grid元素的IsSharedSizeScope要设置为True

UI代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Grid Grid.IsSharedSizeScope="True" Margin="3" ShowGridLines="True">
 6         <Grid.RowDefinitions>
 7             <RowDefinition></RowDefinition>
 8             <RowDefinition Height="Auto"></RowDefinition>
 9             <RowDefinition></RowDefinition>
10         </Grid.RowDefinitions>
11         <Grid Grid.Row="0" Margin="3" Background="LightYellow" ShowGridLines="True">
12             <Grid.ColumnDefinitions >
13                 <ColumnDefinition Width="Auto" SharedSizeGroup="TextLabel"></ColumnDefinition>
14                 <ColumnDefinition Width="Auto"></ColumnDefinition>
15                 <ColumnDefinition></ColumnDefinition>
16             </Grid.ColumnDefinitions>
17             <Label Margin="5">A very long bit of text</Label>
18             <!-- 如果是第一行或者第一列,这个属性可以不声明,默认就是-->
19             <Label Grid.Column="1" Margin="5">More text</Label>
20             <TextBox Grid.Column="2" Margin="5">A text box</TextBox>
21         </Grid>
22         <Label Grid.Row="1">Some text in between the two grids</Label>
23         <Grid Grid.Row="2" Margin="3" Background="LightBlue" ShowGridLines="True">
24             <Grid.ColumnDefinitions>
25                 <ColumnDefinition Width="Auto" SharedSizeGroup="TextLabel"></ColumnDefinition>
26                 <ColumnDefinition></ColumnDefinition>
27             </Grid.ColumnDefinitions>
28             <Label Margin="5">Short</Label>
29             <TextBox Grid.Column="1" Margin="5">A text box</TextBox>
30         </Grid>
31     </Grid>
32 </Window>

运行效果:

Canvas面板使用:

使用绝对定位,如果窗口的大小小于canvas面板,一部分内容会看不见,canvas中的项不能自动调整大小,在canvas内的控件指定左上角,用Canvas.Top和Canvas.Left属性。

例子:

UI层代码(含有Z层顺序):

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525">
 5     <Canvas>
 6         <Button Name="btn1" Content="Button1" Canvas.Left="173" Canvas.Top="108" Width="75" Click="btn1_Click"/>
 7         <!-- Canvas.Left="173" Canvas.Top="108" 这个两个分别表示从左边(顶部)到控件的距离,而且对立方向只能设置一个,即你设置了左边就不能设置右边-->
 8         <Button Name="btn2" Content="Button2" Canvas.ZIndex="1"  Canvas.Right="270" Canvas.Top="185" Width="75" Canvas.Left="294"/>
 9         <!-- Canvas.ZIndex="1" 表示显示的顺序层,数字越大离我们越近,所有控件默认设置都为0-->
10         <DataGrid Canvas.Left="262" Canvas.ZIndex="10"  Canvas.Top="168" Height="62" Width="127"/>
11     </Canvas>
12 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace StackPanel面板
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27         private void btn1_Click(object sender, RoutedEventArgs e)
28         {
29             //设置btn2按钮控件的层顺序为20
30             Canvas.SetZIndex(this.btn2,20);
31         }
32     }
33 }

运行效果:(按下Button1按钮前)

(按下Button2按钮后)

InkCanvas面板使用:

UI层代码:

 1 <Window x:Class="StackPanel面板.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
 5     <Grid>
 6         <Grid.RowDefinitions>
 7             <RowDefinition Height="Auto"></RowDefinition>
 8             <RowDefinition></RowDefinition>
 9         </Grid.RowDefinitions>
10         <StackPanel Grid.Row="0">
11             <ComboBox Name="EditingMode" Margin="5" SelectionChanged="EditingMode_SelectionChanged" />
12             <!-- SelectionChanged="EditingMode_SelectionChanged" 假如ComboBox发生改变,触发EditingMode_SelectionChanged事件-->
13         </StackPanel>
14         <InkCanvas Name="InkC" Grid.Row="1" EditingMode="select">
15             <Button InkCanvas.Left="50" InkCanvas.Top="180" Content="Button1"/>
16         </InkCanvas>
17     </Grid>
18 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace StackPanel面板
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27         private void Window_Loaded(object sender, RoutedEventArgs e)
28         {
29             //历遍InkCanvasEditingMode类型
30             foreach(InkCanvasEditingMode mode in Enum.GetValues(typeof(InkCanvasEditingMode)))
31             {
32                 //把InkCanvasEditingMode类型逐个加入ComboBox下拉多选框(EditingMode)中
33                 this.EditingMode.Items.Add(mode);
34             }
35             //ComboBox下拉多选框默认选项
36             this.EditingMode.SelectedIndex = 0;
37         }
38         //如果ComboBox下拉多选框发生改变
39         private void EditingMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
40         {
41             //改变InkCanvas面板(InkC)属性为ComboBox下拉多选框中所选选项
42             this.InkC.EditingMode = (InkCanvasEditingMode)this.EditingMode.SelectedItem;
43         }  
44     }
45 }

运行效果:

随便测试下功能:

INK(画笔)功能:

Select功能:

补充一点:

Image的Stretch属性:

有时候我们在WPF程序中设置了图片的Width和Height,但图片显示出来的宽和高并不是我们预期的效果,这实际上是由于Image的默认Stretch属性导致的

Image的Stretch属性默认为Uniform,这代表图片会均匀的变大和缩小,保证了图片的比例不失调,而往往我们设置的宽和高并不符合图片的比例,因此显示效果就

不是我们预期所想,Image的Stretch属性还可以设置为以下值:

None —— 图片会按原始大小显示

Fill —— 图片会按照设置的Width和Height显示,比例会失调

UniformToFill —— 图片会按照设置的Width和Height显示,但图片是均匀变大和缩小的,比例不失调,超出显示范围的图像会被截掉

路由事件:

分三种:

1.直接路由事件

2.冒泡路由事件

3.隧道路由事件

冒泡路由事件例子:

UI层代码:

 1 <Window x:Class="WPF路由事件.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525"
 5         MouseUp="SomethingClicked">
 6     <!-- MouseUp="SomethingClicked"设置顶级的路由事件-->
 7     <Grid Margin="3" MouseUp="SomethingClicked">
 8         <Grid.RowDefinitions>
 9             <RowDefinition Height="Auto"/>
10             <RowDefinition Height="*"/>
11             <RowDefinition Height="Auto"/>
12             <RowDefinition Height="Auto"/>
13         </Grid.RowDefinitions>
14         <Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="3" MouseUp="SomethingClicked" 
15                HorizontalAlignment="Left">
16             <!-- Background="AliceBlue" 背景色="AliceBlue", BorderBrush="Black" 笔刷颜色=“黑色”,BorderThickness="3" 边框宽度=“3”,MouseUp="SomethingClicked"设置本级的路由事件-->
17             <StackPanel MouseUp="SomethingClicked">
18                 <TextBlock Margin="3" MouseUp="SomethingClicked">
19                     Image and picture label
20                 </TextBlock>
21                 <Image Height="50" Width="50" 
22                        Source="D:我的文档Visual Studio 2012ProjectsWPF路由事件WPF路由事件Imageplay_button.png" 
23                        Stretch="Uniform" MouseUp="SomethingClicked" />
24                 <!-- Stretch="Uniform" 设置延伸属性,这里表示图片会均匀的变大和缩小,保证了图片的比例不失调,详细看上面补充-->
25                 <TextBlock Margin="3" MouseUp="SomethingClicked">
26                     Courtesy of the StackPanel
27                 </TextBlock>
28             </StackPanel>
29         </Label>
30         <ListBox Margin="5" Name="lstMessages" Grid.Row="1"></ListBox>
31         <CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first event</CheckBox>
32         <Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3">
33             Clear List
34         </Button>
35     </Grid>
36 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace WPF路由事件
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27         protected int eventCounter = 0;
28         private void SomethingClicked(object sender,RoutedEventArgs e)
29         {
30             //object sender 触发事件的对象,RoutedEventArgs e 路由事件(含相关属性)
31             eventCounter++;
32             //sender.ToString() 触发事件的字符化
33             //e.Source 指示引发事件的对象,e.OriginalSource是更深层次的指示引发事件的对象,一般OriginalSource与Source一样
34             string message = "#" + eventCounter.ToString() + ":
" +
35                 "Sender:" + sender.ToString() + "
" +
36                 "Source:" + e.Source + "
" +
37                 "Original Source:" + e.OriginalSource;
38             //ListBox控件lstMessages
39             lstMessages.Items.Add(message);
40             //Handled事件:挂起(即终止,这里是指终止路由事件的传递)
41             e.Handled = (bool)chkHandle.IsChecked;
42         }
43         private void cmdClear_Click(object sender, RoutedEventArgs e)
44         {
45             eventCounter = 0;
46             lstMessages.Items.Clear();
47         }
48     }
49 }

文档大纲:

运行效果(点击前):

(点击后):

隧道路由事件:

修改上面的例子的MouseUp事件为PreviewMouseUp事件即可为隧道路由事件(Preview为隧道路由的标签)

UI层代码:

 1 <Window x:Class="WPF路由事件.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525"
 5         PreviewMouseUp="SomethingClicked">
 6     <!-- PreviewMouseUp="SomethingClicked" 设置顶级的路由事件,加了Preview就是隧道路由事件-->
 7     <Grid Margin="3" PreviewMouseUp="SomethingClicked">
 8         <Grid.RowDefinitions>
 9             <RowDefinition Height="Auto"/>
10             <RowDefinition Height="*"/>
11             <RowDefinition Height="Auto"/>
12             <RowDefinition Height="Auto"/>
13         </Grid.RowDefinitions>
14         <Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="3" PreviewMouseUp="SomethingClicked" 
15                HorizontalAlignment="Left">
16             <!-- Background="AliceBlue" 背景色="AliceBlue", BorderBrush="Black" 笔刷颜色=“黑色”,BorderThickness="3" 边框宽度=“3”,PreviewMouseUp="SomethingClicked" 设置本级的路由事件,加了Preview就是隧道路由事件-->
17             <StackPanel PreviewMouseUp="SomethingClicked">
18                 <TextBlock Margin="3" PreviewMouseUp="SomethingClicked">
19                     Image and picture label
20                 </TextBlock>
21                 <Image Height="50" Width="50" 
22                        Source="D:我的文档Visual Studio 2012ProjectsWPF路由事件WPF路由事件Imageplay_button.png" 
23                        Stretch="Uniform" PreviewMouseUp="SomethingClicked" />
24                 <!-- Stretch="Uniform" 设置延伸属性,这里表示图片会均匀的变大和缩小,保证了图片的比例不失调,详细看上面补充-->
25                 <TextBlock Margin="3" PreviewMouseUp="SomethingClicked">
26                     Courtesy of the StackPanel
27                 </TextBlock>
28             </StackPanel>
29         </Label>
30         <ListBox Margin="5" Name="lstMessages" Grid.Row="1"></ListBox>
31         <CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first event</CheckBox>
32         <Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3">
33             Clear List
34         </Button>
35     </Grid>
36 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace WPF路由事件
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27         protected int eventCounter = 0;
28         private void SomethingClicked(object sender,RoutedEventArgs e)
29         {
30             //object sender 触发事件的对象,RoutedEventArgs e 路由事件(含相关属性)
31             eventCounter++;
32             //sender.ToString() 触发事件的字符化
33             //e.Source 指示引发事件的对象,e.OriginalSource是更深层次的指示引发事件的对象,一般OriginalSource与Source一样
34             string message = "#" + eventCounter.ToString() + ":
" +
35                 "Sender:" + sender.ToString() + "
" +
36                 "Source:" + e.Source + "
" +
37                 "Original Source:" + e.OriginalSource;
38             //ListBox控件lstMessages
39             lstMessages.Items.Add(message);
40             //Handled事件:挂起(即终止,这里是指终止路由事件的传递)
41             e.Handled = (bool)chkHandle.IsChecked;
42         }
43         private void cmdClear_Click(object sender, RoutedEventArgs e)
44         {
45             eventCounter = 0;
46             lstMessages.Items.Clear();
47         }
48     }
49 }

文档大纲:

运行效果(点击前):

(点击后)

另一个隧道路由例子:

UI层代码:

 1 <Window x:Class="WPF路由事件.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         Title="MainWindow" Height="350" Width="525"
 5         PreviewKeyDown="SomeKeyPressed">
 6     <Grid Margin="3" PreviewKeyDown="SomeKeyPressed">
 7         <Grid.RowDefinitions>
 8             <RowDefinition Height="Auto"></RowDefinition>
 9             <RowDefinition Height="*"></RowDefinition>
10             <RowDefinition Height="Auto"></RowDefinition>
11             <RowDefinition Height="Auto"></RowDefinition>
12         </Grid.RowDefinitions>
13         <Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" 
14                HorizontalContentAlignment="Stretch" PreviewKeyDown="SomeKeyPressed">
15             <StackPanel PreviewKeyDown="SomeKeyPressed">
16                 <TextBox Margin="3" HorizontalAlignment="Center" PreviewKeyDown="SomeKeyPressed">
17                     Image and text label
18                 </TextBox>
19                 <Image Source="D:我的文档Visual Studio 2012ProjectsWPF路由事件WPF路由事件Imageplay_button.png" 
20                        PreviewKeyDown="SomeKeyPressed" Width="50" Height="50"/>
21                 <DockPanel Margin="0,5,0,0" PreviewKeyDown="SomeKeyPressed">
22                     <TextBlock Margin="3" PreviewKeyDown="SomeKeyPressed">
23                         Type here:
24                     </TextBlock>
25                     <TextBox PreviewKeyDown="SomeKeyPressed" KeyDown="SomeKeyPressed"></TextBox>
26                 </DockPanel>
27             </StackPanel>
28         </Label>
29         <ListBox Name="lstMessages" Grid.Row="1" Margin="5"/>
30         <CheckBox Margin="5" Grid.Row="2" Name="chkHandle">Handle first event</CheckBox>
31         <Button Click="cmdClear_Click" Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3">
32           Clear List</Button>
33     </Grid>
34 </Window>

逻辑层代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Windows;
 7 using System.Windows.Controls;
 8 using System.Windows.Data;
 9 using System.Windows.Documents;
10 using System.Windows.Input;
11 using System.Windows.Media;
12 using System.Windows.Media.Imaging;
13 using System.Windows.Navigation;
14 using System.Windows.Shapes;
15 
16 namespace WPF路由事件
17 {
18     /// <summary>
19     /// MainWindow.xaml 的交互逻辑
20     /// </summary>
21     public partial class MainWindow : Window
22     {
23         public MainWindow()
24         {
25             InitializeComponent();
26         }
27         protected int eventCounter = 0;
28         private void SomeKeyPressed(object sender, RoutedEventArgs e)
29         {
30             eventCounter++;
31             string message = "#" + eventCounter.ToString() + ":
" +
32                 "Sender:" + sender.ToString() + "
" +
33                 "Source:" + e.Source + "
" +
34                 "Original Source:" + e.OriginalSource + "
" +
35                 "Event:" + e.RoutedEvent;
36             lstMessages.Items.Add(message);
37             e.Handled = (bool)chkHandle.IsChecked;
38             
39         }
40         private void cmdClear_Click(object sender, RoutedEventArgs e)
41        {
42             eventCounter = 0;
43             lstMessages.Items.Clear();
44         }
45     }
46 }

文档大纲:

运行效果(键盘点击前):

(键盘点击后):

原文地址:https://www.cnblogs.com/start-from-scratch/p/5484584.html