2020/11/11
前言
本文主要对初识wpf,wpf主要的布局容器,使用代码来创建wpf程序,路由事件,一些基本的控件进行了解。
提示:以下是本篇文章正文内容,下面案例可供参考
一、初识wpf与使用代码来创建wpf窗体程序
1.初识wpf
-
WPF是微软提供的一种用来开发“桌面应用”的技术(框架),这项技术本身和C#没有关系,必须会的是xaml语法。
-
对XML、HTML、XHTML、ASP.NET之类的“标准通用标记语言”,对于学习是有所帮助的。
-
有WinForm或ASP.NET经验,主要是对控件事件的处理要有所了解。
-
具备面向对象的思想:在WPF中,经常要灵活运用各种继承关系、多态、重载等。
5)其中APP.XAML文件作为设置应用程序的起始文件和资源,MainWindow.xaml与.cs文件作为wpf应用程序界面与xaml设计文件,其中文件开始的两个url非常重要,一个是包含着核心数据,一个是用于一些控件的渲染那些。
代码如下(示例):
<Window x:Class="认识wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:认识wpf"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid x:Name="grid1" HorizontalAlignment="Right" Width="517">
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF5B1D1D" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!--特殊字符以及空白,还有Grid.Row的了解,附加属性-->
<!--<>这个符号由<Button1>表示-->
<Button Content="<Button1>" HorizontalAlignment="Left" Margin="200,45,0,0" Grid.Row="0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="Button2" HorizontalAlignment="Left" Margin="200,35,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75"/>
<Button Content="Button3" HorizontalAlignment="Left" Margin="200,49,0,0" Grid.Row="2" VerticalAlignment="Top" Width="75"/>
<!--这里要让这些空格起作用,那么要用xml:space="preserve"属性-->
<TextBox Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="5,5,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="512" xml:space="preserve">There is has a lot Space" "..</TextBox>
</Grid>
</Window>
namespace 认识wpf
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//顶级元素:window,page,Application(只能有一个顶级元素)
//xmlns第一个:是核心的名称控件.第二个:包含XAMl特性
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Title = this.grid1.Name;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(this.textBox1.Text);
}
}
}
二、wpf常用的几种布局介绍
1)StackPanel:(堆栈面板),通过Orientation属性设置子元素的布局排列方向为“Vertical”(垂直)和“Horizontal”(水平),不写其默认值为“Vertical”,当设置为“Vertical”时子元素会沿水平方向拉伸,反之设置为“Horizontal”时子元素会沿垂直方向拉伸。它的特点是:每个元素各占一行或者一列。
当设置 Orientation="Horizontal"时,按钮按水平方向排列显示,当把StackPanel的FlowDirection属性设置为RightToLeft,Orientation属性设置为Horizontal,StackPanel将从右向左排列元素
代码如下(示例):
<Window x:Class="各种面板比较.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:各种面板比较"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal" FlowDirection="RightToLeft">
<Button Content="button1"></Button>
<Button Content="button2"></Button>
<Button Content="button3"></Button>
<Button Content="button4"></Button>
</StackPanel>
</Window>
2)DockPanel(停靠面板):支持子元素停靠在面板的任意一条边上,通过附加属性Dock控制他们的停靠位置(Left、Top、Right、Bottom),填充空间按照“先到先得”的原则,最后一个加入面板的子元素将填满剩下的空间,如不想将最后加入面板的元素填满剩下的空间将属性LastChildFill值设为“False”,默认为“True”。
如果不想最后那个停靠会填满剩余的区域,就把DockPanel属性LastChildFill设置为false,还必须为最后一个子元素显式指定停靠方向
代码如下(示例):
<Window x:Class="各种面板比较.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:各种面板比较"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<DockPanel LastChildFill="False">
<Button DockPanel.Dock="Left" Content="button1"></Button>
<Button Content="button2" DockPanel.Dock="Bottom"></Button>
<Button Content="button3" DockPanel.Dock="Right"></Button>
<Button Content="button4" DockPanel.Dock="Top"></Button>
<Button Content="button5" DockPanel.Dock="Top"></Button>
</DockPanel>
</Window>
3)WrapPanel(环绕面板):可换行面板与StackPanel相似,通过Orientation属性设置子元素的排列顺序,从左至右按顺序位置定位子元素,当前行无法放下元素时断开至下一行,或者排序按照从上至下或从右至左的顺序进行,通过ItemHeight可以设置当前面板中所有子元素的高度,当然也有ItemWidth设置所有子元素的宽度。
环绕面板将各个控件从左至右按照行或列的顺序罗列,当长度或高度不够时就会自动调整进行换行,后续排序按照从上至下或从右至左的顺序进行。
当Orientation属性的值设置为 Horizontal:元素是从左向右排列的,然后自上至下自动换行(默认值为是Orientation=“Horizontal”)
当Orientation属性的值设置为Vertical:元素是从上向下排列的,然后从左至右自动换行,默认是Horizontal属性的
代码如下(示例):
<Window x:Class="各种面板比较.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:各种面板比较"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical">
<Button Content="button1"></Button>
<Button Content="button1"></Button>
<Button Content="button1"></Button>
<Button Content="button1"></Button>
</WrapPanel>
</Window>
4)Canvas(画布面板):面板是最轻量级的布局容器,它不会自动调整内部元素的排列和大小,不指定元素位置,元素将默认显示在画布的左上方。Canvas主要用来画图。Canvas默认不会自动裁剪超过自身范围的内容,即溢出的内容会显示在Canvas外面,这是因为Canvas的ClipToBounds属性默认值是“False”,我们可以显式地设置为“True”来裁剪多出的内容。下面XAML代码简单演示了Canvas面板的使用。
代码如下(示例):
<Window x:Class="各种面板比较.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:各种面板比较"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas ClipToBounds="True">
<Button Canvas.Left="415" Canvas.Bottom="-80" Height="227" Content="button1"></Button>
</Canvas>
</Window>
- Grid(网格面板):比起其他Panel,功能是最多最为复杂的布局控件。它由<Grid.ColumnDefinitions>列元素集合和<Grid.RowDefinitions>行元素集合两种元素组成。而放在Grid面板中的元素必须显式采用附加属性定义其所在行和列,否则元素均默认放置在第0行第0列。
代码如下(示例):
<Window x:Class="Grid面板.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Grid面板"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<!--UseLayoutRounding:让边缘不会有模糊的样子,会非常清晰-->
<!--ShowGridLines:是否显示线条-->
<Grid ShowGridLines="False" UseLayoutRounding="True">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="2*" MinWidth="50"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!--Grid.Row:处在哪个行 Grid.Column:处在哪个列 Grid.RowSpan占用多少行 Grid.ColumnSpan占用多少列-->
<Button Content="Left Button" Grid.Row="0" Grid.Column="0" Margin="3" Grid.RowSpan="2"/>
<Button Content="Center Button" Grid.Column="2" Grid.Row="0" Margin="5"/>
<Button Content="RightBottom Button" Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="1" Margin="10"/>
<GridSplitter Grid.Column="1" Width="3" Grid.RowSpan="2" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
</Grid>
</Window>
三、wpf事件介绍
1)事件本质来说,他就是能做什么,追求功能的一种机制。
2)但是wpf中为什么称事件为路由事件呢?
一、什么是路由事件
路由事件是一种可以针对元素树中的多个侦听器而不是仅仅针对引发该事件的对象调用处理程序的事件。
路由事件与一般事件的区别在于:路由事件是一种用于元素树的事件,当路由事件触发后,它可以向上或向下遍历可视树和逻辑树,他用一种简单而持久的方式在每个元素上触发,而不需要任何定制的代码(如果用传统的方式实现一个操作,执行整个事件的调用则需要执行代码将事件串联起来)。
路由事件的路由策略:
所谓的路由策略就是指:路由事件实现遍历元素的方式。
路由事件一般使用以下三种路由策略:1) 冒泡:由事件源向上传递一直到根元素。2) 直接:只有事件源才有机会响应事件。3) 隧道:从元素树的根部调用事件处理程序并依次向下深入直到事件源。一般情况下,WPF提供的输入事件都是以隧道/冒泡对实现的。隧道事件常常被称为Preview事件。
下面让我们来详细看看各种事件的使用;
代码如下(示例):
namespace 理解路由事件
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//冒泡事件就是一个一层一层往上传递。
//隧道路由事件就是一层一层往下传递,与冒泡事件相反.
//前面有Preview这个叫隧道路由事件,取消了Preview的叫冒泡路由事件
}
/// <summary>
/// 键盘事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void KeyEvent(object sender, KeyEventArgs e)
{
string message = "Event:" + e.RoutedEvent + " " + "Key:" + e.Key;
this.listMessage.Items.Add(message);
}
/// <summary>
/// 文本框事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextInput(object sender, TextCompositionEventArgs e)
{
string message = "Event:" + e.RoutedEvent + " " + "Key:" + e.Text;
this.listMessage.Items.Add(message);
}
/// <summary>
/// 文本发生变化的时候可以触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string message = "Event:" + e.RoutedEvent;
this.listMessage.Items.Add(message);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.listMessage.Items.Clear();
}
}
/// 鼠标移到捕获坐标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rect_MouseMove(object sender, MouseEventArgs e)
{
Point pt = e.GetPosition(this);
this.IblInfo.Text = ("You are at("+pt.X+","+pt.Y+")in window coordinates");
}
/// <summary>
/// 获得鼠标焦点事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void cmdCapture_Click(object sender, RoutedEventArgs e)
{
Mouse.Capture(this.rect);
this.cmdCapture.Content = "Mousr is now captured.....";
}
//鼠标拖放事件
private void lblSource_MouseDown(object sender, MouseButtonEventArgs e)
{
Label lbl = (Label)sender;
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Copy);
}
private void lblTarget_Drop(object sender, DragEventArgs e)
{
((Label)sender).Content = e.Data.GetData(DataFormats.Text);
}
}
}
当我们看到上面的列子,发现每一个事件,都有她自己的作用,都有着自己的事件本身sender,还有包含着事件参数的类EventArgs e
四、wpf控件
1.用代码和xaml设置前景和背景颜色。
在代码中设置控件前景和背景颜色大多使用SolidColorBrush,SystemColors他们分别是多前景和背景颜色种类的一个封装
代码如下(示例):
<Window x:Class="控件类.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:控件类"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<!--设置背景和前景-->
<!--背景是指(backgroud):控件背景颜色,前景是指(Foregroud):控件上面字体颜色-->
<!--通过xaml来设置颜色-->
<Grid>
<Button Background="Blue" Foreground="Red" Name="button1" Content="Button" HorizontalAlignment="Left" Margin="240,120,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
namespace 控件类
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// 通过代码来设置颜色
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.button1.Background = new SolidColorBrush(Colors.Red);
this.button1.Foreground = SystemColors.ControlDarkBrush;
}
}
}
2.字体
字体中的六大属性:
FontFamily 字体,就是选择宋体,黑体,幼圆等等的属性,当确定FontFamily时,不能使用缩写字符串
FontSize 字体的设备无关单位尺寸
FontStyle 可以设置斜体
FontWeight 设置文本粗细
FontStretch 设置字体拉伸或压缩程度,UltraCondensed减至正常宽度50%
代码如下(示例):
<Window x:Class="控件类.字体"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:控件类"
mc:Ignorable="d"
Title="字体" Height="300" Width="300" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Name="button1" Height="20" Width="50" Content="Button" Background="Yellow" Foreground="Blue"></Button>
<ListBox Name="listBox1" HorizontalAlignment="Left" Margin="80,75,0,0" VerticalAlignment="Top" />
<TextBlock Grid.Row="0" Height="AUTO" FontFamily="Arial" Text="This is First" ></TextBlock>
<TextBlock TextOptions.TextFormattingMode="Display" Grid.Row="1" Name="textBlock2" Height="auto" FontSize="10" Text="This is ass" ></TextBlock>
</Grid>
</Window>
2)字体替换
代码如下(示例):
<Button FontFamily="Technical Italic, Comic Sans MS, Arial" Grid.Row="1" Grid.Column="1"
Margin="40">A Button</Button>
3)字体嵌入
首先向应用程序中添加字体文件(通常是具有.ttf扩展名的文件),并将Build Action选项设置为Resourse(为设置该属性,可在Visual Studio的Solution Explorer中选择字体文件,并在Properties窗口中改变它的Build Action属性)。
接下来在使用字体时,需要在字体家族名称之前添加字符序列“./#”,如下所示:
代码如下(示例):
<Label FontFamily="./#Bayern">...aaa...</Label>
4)文本格式化模式
就是相互对比,让更小的字体看的更加清楚(FontSize<24)
代码如下(示例):
<TextBox FontSize="12" Grid.Row="1" Grid.Column="0" Margin="5">This is a Test. Ideal text
is blurry at small sizes.</TextBox>
<TextBox FontSize="12" Grid.Row="1" Grid.Column="1" Margin="5"
TextOptions.TextFormattingMode="Display">This is a Test. Display text is crisp at small
sizes.</TextBox>
2.内容控件
内容控件,它可以包含显示一块内容。只能包含当个(只能包含的一个子元素)。和布局容器不同,布局容器可以不限制的包含子元素。内容控件都继承于ContentControl类。
1)Content属性
Conent 只接收单一的对象(任何类型),就算其中有嵌套的控件,但是也只能对其中一个设置Content
代码如下(示例):
<StackPanel>
<!--直接设置Content属性-->
<Button Content="button" Margin="5"></Button>
<!--嵌套一个子元素-->
<Button Margin="5">
<TextBlock>this is TextBlock</TextBlock>
</Button>
<!--包含一个布局元素来实现嵌套多个子元素-->
<Button Margin="5">
<StackPanel>
<Label BorderBrush="Black" BorderThickness="1">this is Label</Label>
<Label BorderBrush="Aquamarine" BorderThickness="1" >this is Label</Label>
<Label BorderBrush="Beige" BorderThickness="1">this is Label</Label>
</StackPanel>
</Button>
</StackPanel>
2)设置对齐方式和ToolTip
ToolTip:鼠标移动到该元素时,显示提示内容
代码如下(示例):
<Button Content="button" ToolTip="ToolTip case" Margin="5" HorizontalContentAlignment="Left" ></Button>
<Button Content="button" Margin="5" HorizontalContentAlignment="Right" ></Button>
3)标签
标签具有记忆符,记忆符是能够为连接的控件设置焦点的快捷键。
代码如下(示例):
<Label Target="{Binding ElementName=txtA}">Choose A</Label>
<TextBox Name="txtA"></TextBox>
4)按钮
a.IsCancel属性,true按钮就成为窗口的取消按钮。在当前窗口的任何位置如果按下Esc键,就会触发该按钮。
b.IsDefault属性,true,按钮就会成为默认按钮。默认按钮具有蓝色阴影。如果焦点位于非按钮控件上,按enter就会触发默认按钮。如果焦点在按钮上就会触发当前按钮。
c.ToggleButton控件和RepeatButton
d.GridViewColumnHeader类,当使用基于网格的ListView控件时,该类可以表示一列可以单击的标题。
e.RepeatButton类,只要按钮保存按下的状态,该类就不断地触发Click事件。
f.ToggleButton类,改类表示有两个状态(按下按钮和未按下按钮)。当单击ToggleButton时,它会保持按下状态,直到再次单击改按钮以释放它为止。
5)CheckBox控件
继承自ToggleButton,有"开关"行为。
IsChecked:true、false、null。null表示不确定的状态,带有阴影的复选框。
代码如下(示例):
<CheckBox IsChecked="{x:Null}">checkbox</CheckBox>
- RadioButton控件
RadioButton类也继承自ToggleButton类。增加了GroupName属性,改属性用于控制如何对单选按钮进行分组。
单选按钮通常由它们的容器就行分组。这意味着,如果StackPanel面板中放置三个单选按钮,那么这三个单选按钮就形成了一组,而且只能选择这三个按钮中的一个。
# 总结 提示:这里对文章进行总结: 例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。