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是类
xmlns是XML 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 }
运行效果:
附上源代码文件:
使用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 }
文档大纲:
运行效果(键盘点击前):
(键盘点击后):