前言

总目录
在上一章中,初步的认识了WPF,那么这一章将逐个的认识一些常用的控件以及这些控件的常用属性,这对于我们我们后续开发WPF程序是非常有必要的。


一、Window窗体

1、Window基本用法

(1)Winodw窗体派生自ContentControl,有一个Content属性,里面可以放一个任意控件,因此Window下只可放一个子元素

(2)Window常用属性:Icon设置窗体的图标,ShowInTaskbar 是否在任务栏项目窗体图标,WindowState 窗口显示方式等等还有很多,可以自行设置看看。

2、去除原生边框,设置自定义背景和圆角的窗体

日常开发中:最常用的是,去掉原生的Window边框,实现自定义背景且圆角带阴影的窗体,
代码如下:

<Window x:Class="WpfApp1.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:WpfApp1" Width="800" Height="400"Title="MainWindow" WindowStyle="None" WindowStartupLocation="CenterScreen"  AllowsTransparency="True" Background="Transparent"MouseLeftButtonDown="Window_MouseLeftButtonDown" ><Grid><Border CornerRadius="15" Background="SeaGreen" Margin="15"><Border.Effect><DropShadowEffect Color="#800F0E0E" ShadowDepth="5"></DropShadowEffect></Border.Effect></Border></Grid>
</Window>

首先WindowStyle="None"去掉原生边框,设置AllowsTransparency=“True” 和Background=“Transparent” 将背景变为透明的,后续窗体具体怎么呈现可以交给里面的子元素去定义。

后台代码:

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){this.DragMove();//这个的意思是允许鼠标拖动窗体}

3、窗体生命周期

当启动到关闭一个项目,一个窗体的生命周期(顺序如下):

窗体事件 描述
1 SourceInitialized 资源初始化的时候
2 Activated 窗体激活的时候,窗体默认为激活状态
3 Loaded 窗体加载的时候
4 ContentRendered 内容呈现的时候
5 Deactivated和Activated 在切换不同的窗体的时候,这个状态会不断的切换,一直触发这个两个事件
5 Closing 准备关闭窗体时
6 Deactivated 窗体失去焦点,失活状态
7 Closed 窗体关闭时

二、Border 边框

通常与布局面板Grid 一起使用,如上面案例中即是如此,也可作为任意控件的边框也多用在控件的模板中定义控件的边框
常用属性:圆角CornerRadius,边框大小BorderThickness,边框颜色BorderBrush

<Border CornerRadius="15" Background="SeaGreen" Margin="15" BorderThickness="10" BorderBrush="Black">

三、布局控件

1、Grid

(1)Gird面板可以定义行和列,形成一个灵活的网格区域。再通过附加属性:Grid.Column=“0” 和Grid.Row=“1” 以及Grid.RowSpan=“3” 和Grid.ColumnSpan="2"等设置控件属于哪行哪列就可以进行精确的定位布局。

常用属性 描述
Grid.Column=“0” 表示位于哪列,从0开始
Grid.Row=“1” 表示位于哪行,从0开始
Grid.RowSpan=“3” 表示横跨几行
Grid.ColumnSpan=“2” 表示横跨几列
ShowGridLines 显示网络线,默认不显示,显示出来可以方便调试定位
ColumnDefinition和ColumnDefinitions 用于定义列
RowDefinition和RowDefinitions 用于定义行

(2)设置尺寸的方式

设置方式 描述
绝对数值 如 With=“100”
自动设置 如 Width=“Auto”
按比例设置 如 Height="2*”

(3)综合应用

    <Grid Background="BlueViolet"><Grid.ColumnDefinitions><ColumnDefinition Width="100"/><ColumnDefinition/><!--默认就是Auto--><ColumnDefinition Width="100"/><!--左右两列固定了宽度的时候,中间的如果不定义那么就是默认自动,将会自动撑满剩余控件--></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="50"/><RowDefinition Height="*"/><RowDefinition Height="2*"/><!--第一行固定了高度,那么剩余的设置了*和2*,那么剩余空间将会按照1比2的形式分配--></Grid.RowDefinitions><!--通过Grid.Column="0" Grid.Row="0"定义内部子元素的位置--><Grid Grid.Column="0" Grid.Row="0" Background="Wheat"></Grid><Grid Grid.Column="0" Grid.Row="1" Background="Red"></Grid></Grid>

(4)共享尺寸
共享尺寸,通过在父级Grid上设置Grid.IsSharedSizeScope=“True”,然后在子元素上设置SharedSizeGroup 共享组名称,如果名称相同,则会共享尺寸。

   <Grid Grid.IsSharedSizeScope="True"><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="3*"/></Grid.RowDefinitions><Grid Background="AliceBlue"  ><Grid.ColumnDefinitions><ColumnDefinition Width="100" SharedSizeGroup="col1"/><ColumnDefinition Width="3*"/></Grid.ColumnDefinitions><Grid Background="Bisque"></Grid><GridSplitter Width="4" Background="Red"></GridSplitter></Grid><Grid Grid.Row="1" Background="Aquamarine" ><Grid.ColumnDefinitions><ColumnDefinition  SharedSizeGroup="col1" /><ColumnDefinition Width="3*"/><ColumnDefinition Width="3*"/></Grid.ColumnDefinitions><Grid Background="Bisque"></Grid><Grid  Grid.Row="1" Background="Red"><Button></Button></Grid></Grid></Grid>

效果如下:

2、UniformGrid

        <UniformGrid Rows="2" Columns="5"><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/><Button Height="50" Width="50" Content="Button"/></UniformGrid>

相较于Grid,UniformGrid没有附加属性不会对子元素进行点位,会根据设置的Rows和Columns均分内部空间。如果没有设置Rows和Colums则会对内部的子元素根据子元素数量均分内部的空间,所有所谓的分行分页,具体行列取决于内部有多少子元素。

3、StackPanel

(1)派生自Panel,主要用于布局和排列,内部可以放多个控件。它可以将子元素进行水平或者竖直的排列,超过自己范围的子元素将会隐藏,不会自动切换到下一行或列,里面的子元素的位置也不可随意拖动,只能通过Margin设置子元素间的间隔
(2)常用属性

常用属性 描述
Orientation=“Horizontal” 该属性设置子元素的排列方式,Horizoontal表示水平堆放,Vertical竖直堆放,默认Vertical
FlowDirection=“LeftToRight” 流动方向,只对Orientation=“Horizoontal” 有效,表示控件是从左到右LeftToRight,还是从右到左排列RightToLeft

(3)应用
通常用于将控件按照行或列排列布局,与其他布局控件配合使用

 <!--承接Grid中的案例,将StackPanel放在第2列,然后从0行开始,占据2行--><StackPanel Background="Azure" Grid.Column="1" Grid.RowSpan="2" Orientation="Vertical" ><StackPanel Width="50" Background="Black" Height="50"></StackPanel><StackPanel Orientation="Horizontal" FlowDirection="RightToLeft"><Button Height="40" Width="40" Background="Beige" Margin="10"></Button><Button Height="40" Width="40" Background="Beige" Margin="10"></Button><Button Height="40" Width="40" Background="Beige" Margin="10"></Button></StackPanel></StackPanel>

4、WrapPanel(自动换行换列)

(1) 这个控件也是按行按列排列子元素,是对WrapPanel的补充,在StackPanel的基础上,增加了自动换行换列的功能。
(2)常用属性

常用属性 描述
Orientation=“Horizontal” 该属性设置子元素的排列方式,Horizontal表示水平堆放,Vertical竖直堆放,默认Vertical
FlowDirection=“LeftToRight” 流动方向,只对Orientation=“Horizontal” 有效,表示控件是从左到右LeftToRight,还是从右到左排列RightToLeft
ItemWidth&ItemHeight 设置子元素的宽高,设置后子元素均是设置的宽高

(3)应用

<WrapPanel Background="Black" Grid.Column="0" Grid.Row="2" ItemWidth="20" ItemHeight="20" FlowDirection="RightToLeft"><Button Background="Beige" Margin="2"></Button><Button Background="Beige" Margin="2"></Button><Button Background="Beige" Margin="2"></Button><Button Background="Beige" Margin="2"></Button><Button Background="Beige" Margin="2"></Button><Button Background="Beige" Margin="2"></Button>
</WrapPanel>

5、DockPanel

(1)定义一个区域,DockPanel中的子元素可以按相对位置水平或竖直排列,子元素不可以随意拖动
(2)常用属性

常用属性 描述
LastChildFill=“True” 默认最后一个元素,填空剩余控件,如果改为false将不填充
DockPanel.Dock=“Left” 通过附加属性设置子元素在DockPanel的位置,Top,Right,Left,Right

(3)布局自适应页面

  <DockPanel Background="White" Grid.Column="1" Grid.Row="2" LastChildFill="True"><Button Height="50" Width="50" DockPanel.Dock="Bottom" Content="Bottom"></Button><Button Height="50" Width="50" DockPanel.Dock="Left"  Content="Left"></Button><Button Height="50" Width="50" DockPanel.Dock="Top"  Content="Top"></Button><Button Height="50" Width="50" DockPanel.Dock="Right"  Content="Right"></Button><!--最后一个不设置大小的情况下:默认填空剩余控件--><Button></Button></DockPanel>

6、Canvas

常用属性 描述
Canvas.Left 通过使用附加属性,如Canvas.Left 和Canvas.Top来定位子元素在Canvas内部的位置。如果Canvas大小发生了变化,内部的子元素位置也会发生变化,但是子元素相对于Canvas的位置是不变的。
ClipToBounds=“False” Canvas是默认允许子元素超出自己边界的,不会裁剪;设置ClipToBounds="True"则会裁剪

1 每个元素必须使用附加属性指定位置,否则都会出现在左上角。
2 Canvas 不能在指定位置时超过2个坐标,如:Canvas.Left=“10” Canvas.Top=“10” Canvas.Right=“10”
那么最后一个将会失效。

        <Canvas Height="100" Width="100" Background="Red" ClipToBounds="False"><Button Height="20" Width="200" Canvas.Left="10" Canvas.Top="10"></Button></Canvas>

如下图所示:

7、ViewBox

定义一个内容修饰器,以便拉伸或缩放单一子项使其填满可用的控件

常用属性Strech

Strech属性枚举值 描述
None 不做缩放,放入子元素控件的大小保持不变
Fill 拉伸子元素控件以填满整个ViewBox内部的控件,有可能会导致变形
Uniform 内部子元素如果设置了宽高,那么ViewBox会将子元素按照宽高比例去缩放。如果子元素宽为200,高100,那么无论窗口如何调整大小,该子元素控件会永远保持2:1的比例在ViewBox内去填充,但不一定填满整个控件。
UniformToFill 内部子元素同样会保持自己的纵横比并且一定会填满整个控件,但是超过ViewBox的部分将会被裁剪
    <Viewbox Stretch="Uniform"><!--ViewBox内只可放一个子元素,设置的Stretch=Uniform 则表示不管窗体大小如何变化,子元素都将保持这个比例等比缩放--><Grid Width="1920" Height="1080" Background="Aqua"><!--里面还可以放置其他的控件--></Grid></Viewbox>

7、Panel.ZIndex附加属性在布局中的使用

      <StackPanel Orientation="Horizontal"><Grid Height="100" Width="100" VerticalAlignment="Top"><Button Width="80" Height="80"></Button><Button Width="40" Height="40" Background="Red"></Button></Grid><Grid Height="100" Width="100" VerticalAlignment="Top"><Button Width="80" Height="80" Panel.ZIndex="1"></Button><Button Width="40" Height="40" Background="Red"></Button></Grid></StackPanel>


默认同一个位置,控件的叠放是后面的控件就放置在上层,如果设置Panel.ZIndex则可以按照自定义的叠放顺序放置。

四、按钮与输入框

1、Button

常用属性 描述
Content=“按钮” 直接设置或者使用在<Button>标签内放一个子控件
Click 点击事件,一般点击按钮后做什么业务逻辑都在这里
Command 在开发项目时会使用到,可以绑定命令,效果同Click
IsDefault 当用户按下Enter的时候,相当于点击该按钮,就会调用该按钮的点击事件,多用于登录界面
IsCancel 当用户按下Esc的时候相当于点击了该按钮,同样登录界面用的较多
      <Button Height="40" Width="100" Background="Beige" Margin="10" Click="Button_Click" IsCancel="True" IsDefault="True" Command="{Binding xxCommand}"><TextBlock Text="按钮Content"></TextBlock></Button>

2、ReapButton

作用是当用户鼠标左键按住该按钮时,会一直触发点击事件,主要应用于一些播放器的快进等功能

<RepeatButton  Delay="20" Interval="1000" Click="repButton_Click"></RepeatButton>
常用属性 描述
Delay 表示从用户按下鼠标左键到开始重复发送Click事件的延迟时间(毫秒),Delay的数值必须>=0。
Interval 表示当用户按下鼠标左键时,每次发送Click事件的时间间隔(毫秒),Interval的数值必须>=0。

3、TextBox

<TextBox Width="100" Height="40" TextWrapping="Wrap" TextAlignment="Center" Text="1234546546484684684646456464646">
常用属性 描述
Text 文本内容
TextWrapping 文本是否自动换行,默认一行显示
TextAlignment 文本对齐方式

4、PasswordBox

<PasswordBox Password="1213113" PasswordChar="*" Width="80" Height="30"VerticalContentAlignment="Center" HorizontalContentAlignment="Right"></PasswordBox>
常用属性 描述
Password 密码文本信息
PasswordChar 密码字符,默认是圆点
VerticalContentAlignment & HorizontalContentAlignment 设置内部密码文本的对齐方式

5、RichTextBox

(1)对System.Windows.Documents.FlowDocument对象进行丰富操作的编辑控件,与TextBox一样派生自TextBoxBase

常用属性 描述
Document 获取或设置RichTextBox的SystemWindows.Documents.FlowDocument表示的内容
IsDocumentEnabled 用户是否可以交互(RichTextBox中的UIElement和 ContentElement中的对象),false用户将无法操作文档内容进行交互
Selection 当前选定内容

(2)FlowDocument 可以设置一些文档通用的属性,属性如下:

【ColumnGap列间隔】、 【PageWidth页宽】、 【lsColumnWidthFlexible列宽是灵活还是固定】
【ColumnRuleBrush绘制列之间标尺的颜色】、 【PagePadding页内边距】 、【PageHeight页高度】、 【ColumnWidth列宽】、【Blocks内容的顶级块元素】、 【FlowDirection流中的内容的相对方向】、 【ContentStart内容的开始位置】 、【ContentEnd内容的结束位置】、【LineHeight各行内容的高度】还有各种文字属性FontFamily,FontSize,FontWeight等等

(3)FlowDocument中的元素:

常用属性 描述
Block 为所有块级别流内容元素提供基类的抽象类
Paragraph 用于将内容分组到一个段落中的块级别流内容元素
Run 旨在包含一连串格式化或非格式化文本的内联级别流内容元素。Inline
Section 用于对其他 System.Windows.Documents.Block元素进行分组的块级别流内容元素
Hyperlink 提供用于在流内容中承载超链接的功能的内联级别的流内容元素
InlineUIContainer 内联级别的流内容元素,可以将UI元素嵌入到流内容中
BlockUlContainer 块级别流内容元素可以将UI元素嵌入到流内容中

(4)案例

        <Grid Width="1920" Height="1080" Background="Aqua"><!--默认IsDocumentEnabled是不可交互的--><RichTextBox IsDocumentEnabled="True" ><!--【1】我是FlowDocument是一个文档,RichTextBox用我来承接内容--><!--我可以设置文档的对齐方式,以及基本的字体大小,颜色,列间隔,页宽,行高等等文档的属性--><FlowDocument PagePadding="20" TextAlignment="Center" PageWidth="1500"><!--【2】Paragraph是文档中的一个段落--><Paragraph TextIndent="20" LineHeight="80" Background="Red" ><!--可以设置行高LinHeight 与 缩进TextIndent--><Run Text="行内元素Run是放在Paragraph中的,一般表示一句话。" FontSize="40"></Run><Run Text="我也是行内元素Run,我接着上一个Run,我们之间不换行" FontSize="40" Foreground="Aqua"></Run></Paragraph><!--段落与段落之间是要换行的--><Paragraph TextIndent="20" LineHeight="100" TextAlignment="Center"  Foreground="Blue" Background="BlanchedAlmond"><Run Text="我是第二个Paragraph中的内容,与上一个段落是要换行的" FontSize="60"></Run><!--我是行内元素,超链接--><Hyperlink  Click="Hyperlink_Click" FontSize="40"><Run Text="网址"  ></Run><Run Text="dawd"></Run><TextBlock Text="我是UI元素也可以放在这里" ></TextBlock></Hyperlink></Paragraph><Paragraph TextIndent="20" Foreground="Blue" Background="BlanchedAlmond" FontSize="30"><!-- 一般文档中的行内元素放在InlineUIContainer中,InlineUIContainer只能放一个子元素--><Run Text="我是Run元素哦,后面是InlineUIContainer"></Run><InlineUIContainer><TextBlock Text="我是放在InlineUIContainer里的TextBlock"></TextBlock></InlineUIContainer><!--由此可见Run 和 InlineUIContainer中的内容是不换行的--></Paragraph><!--我是BlockUIContainer,是换行的--><BlockUIContainer ><TextBlock Text="我是放在BlockUIContainer里的TextBlock" FontSize="40"></TextBlock></BlockUIContainer><BlockUIContainer ><TextBlock Text="我是放在BlockUIContainer里的TextBlock" FontSize="40"></TextBlock></BlockUIContainer></FlowDocument></RichTextBox></Grid>
        private void Hyperlink_Click(object sender, RoutedEventArgs e){Process process = new Process();process.StartInfo.FileName = "www.baidu.com";process.Start();}


以上介绍了RichTextBox的基本属性和用法,对于RichTextBox一般还有有一些文本编辑功能,如复制粘贴,设置对齐方式,插入文本,保存文件等等内容还是比较多的,后续有机会在进行专题讲解

五、文本控件

1、TextBlock

(1)这是一个轻量级的文本控件,多用于一些简短的标题或文字,或者成为内容控件的子元素作为文本呈现用。

(2)一般用法如下:

      <StackPanel><!--【1】单独使用--><TextBlock Text="###大标题" TextWrapping="Wrap" FontSize="30"></TextBlock><!--【2】内部组合使用,多用于一些界面上标题后面还接着一行小英文标题--><TextBlock><TextBlock Text="一级大标题" FontSize="30"></TextBlock><TextBlock Text="二级标题" FontSize="20"></TextBlock><Run Text="最后解释语" FontSize="10"></Run></TextBlock><!--【3】作为其他元素的子元素使用--><Button Height="20" Width="220"><Button.Content><TextBlock Text="我是作为按钮的Content呈现的"></TextBlock></Button.Content></Button></StackPanel>

2、Label

(1)一个可以具有Content属性的文本控件,一般用作文本显示。
由于该控件具有Content属性,因此可以在Content 中组合多个子元素控件来显示内容,这样显示的内容就更加丰富了。

  <Label Content="我是Label" BorderThickness="1" BorderBrush="Black"></Label><Label><Label.Content><StackPanel Orientation="Horizontal"><TextBlock Text="1213dww" VerticalAlignment="Center"></TextBlock><Button Height="40" Width="40"></Button></StackPanel></Label.Content></Label>

六、单选和多选框

1、RadioButton单选框

一般多用于选择性别,开关状态等设置

常用属性 描述
Content 按钮的内容
GroupName 组名,这个在使用中需要注意,如果多个RadioButton设置了同一个组名,那么它们之间是互斥的,只有一个能被选中,不同组的不互斥
IsChecked 是否选中的状态
<RadioButton IsChecked="True" Content="男" GroupName="sex"></RadioButton>
<RadioButton  Content="女" GroupName="sex"></RadioButton>

2、CheckBox多选框

多选框一般多用于爱好选项,权限选择等一些需要选择多项内容的场景

常用属性 描述
Content 按钮的内容
IsThreeState 确定控件是否支持两个或三个状态,默认为false,支持三个状态
IsChecked 是否选中的状态
 <StackPanel Orientation="Horizontal"><CheckBox Content="羽毛球" Margin="10" IsChecked="True"></CheckBox><CheckBox Content="足球" Margin="10" IsThreeState="True"></CheckBox><CheckBox Content="篮球" Margin="10"></CheckBox><CheckBox Content="乒乓球" Margin="10"></CheckBox></StackPanel>

单选框和多选框都具有 Checked 已选中时事件,UnChecked 未选中的事件,Click点击的事件用于处理其选择时的逻辑

七、Image

1、基本使用

用于展示图片,主要属性就是Source图片资源路径

<Image Height="100" Width="50" Source="Images/1.jpg" Stretch="Uniform"> </Image>

2、修改数据文件的生成操作

什么是数据文件呢?
数据文件,其实指的就是应用程序依赖的非可执行文件,例如xaml、图像、视频等。如1.jpg。
wpf支持对数据文件进行配置、识别及使用。在wpf中对数据文件分为三类:

  1. 资源文件—被编译进可执行文件exe或者类库dll的数据文件
  2. 内容文件—与程序集有显式关联关系的独立的数据文件
  3. 源站点文件—与程序集没有关联的独立数据文件

如下图所示:如果我们将生成操作设置Resource,那么该文件就是资源文件。会被编译进exe或dll中。
如果生成操作设置为内容,那么重新生成之后,该文件就是内容文件。内容文件会在编译后输出到Debug/Release目录下。如果内容文件是项目的背景图片,则可以直接在Debug目录下通过更换图片实现更换背景。

【生成操作=内容】 通常配合【复制到输出目录=始终复制】一起使用。

3、研究Image中的Source的赋值

查看官方文档中:ImageSource的派生关系
方式一:通过BitmapSource的Create方法

// Define parameters used to create the BitmapSource.
PixelFormat pf = PixelFormats.Bgr32;
int width = 200;
int height = 200;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;
byte[] rawImage = new byte[rawStride * height];// Initialize the image with data.
Random value = new Random();
value.NextBytes(rawImage);// Create a BitmapSource.
BitmapSource bitmap = BitmapSource.Create(width, height,96, 96, pf, null,rawImage, rawStride);// Create an image element;
Image myImage = new Image();
myImage.Width = 200;
// Set image source.
myImage.Source = bitmap;

方式二:通过BitmapSource的派生类BitmapImage(大多是这种方式)

 this.img.Source = new BitmapImage(new Uri("Images/1.jpg", UriKind.Relative));

后续开发中会存在多种给Source赋值的情况,不过各种图片数据大多最终转为为BitmapImage然后赋值给Source

4、相对路径&绝对路径&Pack Uri的使用

1 相对路径的使用(无论是将图片设为资源 还是内容,访问都是没有问题的):

 this.img.Source = new BitmapImage(new Uri("Images/1.jpg", UriKind.Relative));

2 绝对路径的使用:

  • 使用AppDomain,直接到Debug/Release下找文件
    这种绝对路径引用的文件是可以完全独立于项目之外的,操作上只需代码中指定路径后,在Debug/Release目录下,建立该文件的路径,程序即可找到。这种是独立于程序之外,因此不在乎该文件是编译成资源,还是内容。
//Debug目录下新建一个Imgs,然后将1.jpg放进去,只要指定过路径,就可以引用进项目使用
this.img.Source=new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory+ "Imgs/1.jpg", UriKind.Absolute));
  • Pack Uri方式设置绝对路径

如果我们使用的文件的生成操作为Resource, 则此文件为资源文件,
可使用pack://application的方式,引用此资源文件:

this.img.Source=new BitmapImage(new Uri("pack://application:,,,/Images/1.jpg", UriKind.Absolute));

如果我们使用的文件的生成操作为内容, 则此文件为内容文件,
可使用pack://application的方式,引用此内容文件:

this.img.Source=new BitmapImage(new Uri("pack://application:,,,/Images/1.jpg", UriKind.Absolute));

从上面看起来,好像都一样,那么内容文件和资源在使用pack://application:,方式引用上有什么区别呢?
区别在于:如pack://application:,/Images/1.jpg改为pack://application:,/Images/2.jpg,并且2.jpg不在项目的Images的目录下,那么即使项目生成后在Debug/Release目录下加一个Images,Images里放个2.jpg,一样无法引用2.jpg。因为内容文本独立但是和与程序集有显式关联关系,显示关联的特征就是包含在项目结构目录下

源站点文件指的是与程序集没有必然关联关系的独立数据文件,需要
使用pack://siteoforigin去引用资源:

//表示要在程序集dll或者exe之外去找文件
//如果在该文件属性的生成操作设置资源的情况下,这个路径下将无法找到1.jpg
//这种效果同AppDomain.CurrentDomain.BaseDirectory类似
this.img.Source = new BitmapImage(new Uri("pack://siteoforigin:,,,/Images/1.jpg", UriKind.Absolute));

八、其他

1、Slider

Slider滑块通常用于调整数值范围的阀门控件

常用属性 描述
Value 当前刻度值
Minimum 最小刻度
Maximum 最大刻度
Orientation 滑块的方向,Horizontal为水平方向
TickPlacement 刻度的位置,Both表示上下都有刻度
IsSnapToTickEnabled 将滑块移动到最近的刻度线,默认为False,不会将滑块每次的移动都调整到客户线处
IsDirectionReversed 将刻度调转方向,默认False刻度从左到有;设置为Ture后,将会调整为从右到左
IsSelectionRangeEnabled 默认False,不可以选择刻度范围,设置为Ture后,SelectionStart和SelectionEnd的属性值才能生效
SelectionStart,SelectionEnd 刻度范围的开始结束值,一般可用于某个数字的正常范围设定
<Slider Width="300" VerticalAlignment="Top" TickFrequency="10" TickPlacement="Both"
Minimum="0" Maximum="100"  Orientation="Horizontal" LargeChange="20"
IsSnapToTickEnabled="True" IsDirectionReversed="True"
IsSelectionRangeEnabled="True" SelectionStart="10" SelectionEnd="30"></Slider>

2、其他

DatePicker
Carlender
ProgressBar
ToolBar
ToolBarTray
StatusBar
TreeView
ScrollViewer
WindowFormsHost
MediaElement
Rectangle
Eillpse
Polygon
Path
GroupBox,
Expander.
Frame,
TabControl,
ComboBox,
ListBox,
ListView,
DataGrid,
Menu,
ContextMenu,
以上控件详细介绍会逐步更新

如想详细了解以上控件或者更多的控件可以查看:
官方文档:System.Windows 命名空间
官方文档:System.Windows.Controls 命名空间

九、Dispatcher

在我们了解了控件的基本使用和属性之后,在使用控件的过程就不可避免的会遇到一个跨线程操作UI的问题。而Dispatcher就可以解决这个问题。

1、Dispatcher的作用

(1)在WPF中Dispatcher的作用 是为管理的线程的工作项队列提供服务
WPF中的主线程负责:接收输入,处理事件,绘制UI等工作。正因UI界面是由主线程创建并维护,因此子线程不能是直接更改由主线程负责处理的UI界面,如果强行更改就会报错。为了解决这一问题Dispatcher中提供了Invoke 和BeginInvoke两个方法。
(2)具体原理:
先看Invoke 和BeginInvoke的方法,方法原型如下:

public void Invoke(Action callback);
public DispatcherOperation BeginInvoke(Delegate method, params object[] args);

在结合看一下WinForm中对这两个方法的解释会更容易理解,WinForm的解释如下。

Control.Invoke (Delegate method) :在拥有此控件的基础窗口句柄的线程上执行指定的委托。
Control.BeginInvoke(Delegate method) :在创建控件的基础句柄所在线程上异步执行指定委托。

其实WPF中控件使用Control.Dispatcher.Invoke()和WinForm中差不多的意思,只不过WPF又封装了一层上去。
结合以上内容我们知道,其实本质上就是在子程序中,通过Invoke 和BeginInvoke将需要做的UI操作以委托的形式交给了UI主线程去操作,那么这样就解决了跨线程操作的问题。

2、跨线程案例说明:

如果子线程直接操作主线程UI,将会报错。如下图所示:

通过Dispatcher调用则不会报错。

        private void Window_Loaded(object sender, RoutedEventArgs e){Task task = new Task(() =>{while (true){this.tbk_Date.Dispatcher.Invoke(() =>{this.tbk_Date.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");});Thread.Sleep(800);}});task.Start();}

3、Invoke和BeginInvoke的区别

Invoke是在UI线程同步执行操作
BeginInvoke是在UI线程上异步执行操作
案例如下:

由上面案例可知:使用Invoke是在UI线程上同步执行的,上一个操作做完,才可以做下一个。
但是BeginInvoke就是异步执行的,并不是按调用顺序一个个执行,而是无序的异步执行。


总结

总目录
以上就是今天要讲的内容,本文介绍了日常开发过程中经常会使用到的控件,了解这些控件和属性对于我们日后的开发是必不可少的储备知识。

第二章:WPF常用控件介绍相关推荐

  1. winform常用控件介绍

    winform常用控件介绍 1.窗体 1 2.Label 控件 3 3.TextBox 控件 4 4.RichTextBox控件 5 5.NumericUpDown 控件 7 6.Button 控件 ...

  2. Qt常用控件介绍(一)

    Qt常用控件介绍 Qt Creator 的使用技巧 Qt Creator的常用快捷键 按钮 QPushButton QToolButton QRadioButton QCheckBox QComman ...

  3. C#WPF 常用控件

    一.常用控件 1.(1).Border(边框)放到其他控件内部,给其他控件画边框,其他容器必须支持双标签.(2).Background决定背景颜色,BorderBrush决定边框颜色,BorderTh ...

  4. C# Winform 常用控件介绍

    1.窗体 1.常用属性 (1)Name属性:用来获取或设置窗体的名称,在应用程序中可通过Name属性来引用窗体. (2) WindowState属性: 用来获取或设置窗体的窗口状态. 取值有三种: N ...

  5. 【WPF】WPF 常用控件

    目录 一.WPF的概述 1.1 WPF 简介 1.2 WPF 特点 二.XAML 2.1 对象元素语法 2.2 XAML 根元素 2.3 WPF 和 XAML 命名空间声明 三.控件的继承关系 四.常 ...

  6. Kanzi学习之路(3):Kanzi的树形结构和常用控件介绍

    今天我们来通过kanzi studio,感性的了解一下kanzi App的结构和一些常用的控件. 首先我们先新建一个工程,lesson3,通过前面的学习,对于kanzi studio的交互界面有了初步 ...

  7. C#窗体应用程序常用控件介绍

    下面图片列出了我目前常用的一些控件: 1. 窗体Form 新建一个C#窗体应用程序,默认都会有一个窗体控件,窗体就是我们应用程序最大的那个窗口了. 窗体常用的属性有: (1)StartPosition ...

  8. Android常用控件有哪些?如何使用?

    Android常用控件介绍及使用 控件 TextView 显示文字,相当于Panel ImageView 显示图片 EditText 输入框,可编辑,可设置软键盘方式 Button 按钮,可附带图片 ...

  9. WPF(一) WPF基本控件与布局

    ​ WPF(Windows Presentation Foundation)是微软推出的基于Windows的用户界面框架,中文译为"Windows呈现基础",属于.NET Fram ...

最新文章

  1. python怎么安装numpy库-python怎么安装numpy库
  2. 8.Spring Cloud Alibaba教程:整合Seata分布式事务
  3. String转BigDecimal,BigDecimal常用操作,以及避免踩坑
  4. 球体表面积原来还可以这么求!
  5. oracle系统实验,实验1 启动Oracle系统
  6. 搞怪放屁微信小程序源码-无需服务器即可搭建
  7. javascript设计模式——Publish/Subscribe
  8. listview选中高亮
  9. 解决Latex编译报错:Command `\Bbbk‘ already defined. ...ol{\Bbbk} {\mathord}{AMSb}{“7C}
  10. 怎样通过java用web3j查询以太坊交易信息?
  11. linux 编译java web_linux:搭建java web环境
  12. 基于matlab的简易诊断系统,基于matlab的图像识别
  13. 转载-史密斯(smith)圆图讲解-基础内容
  14. 知网研学不同电脑端同步无效问题
  15. 4、c++头文件、源文件使用小记
  16. 2022 CCF国际AIOps挑战赛决赛暨AIOps研讨会成功举办
  17. 使用二手书App的心得
  18. python实现推广小项目
  19. Docker常用操作帅哥专供版
  20. java怎么读取数据?

热门文章

  1. 桌面记事本软件测试培训,记事本程序测试用例及编写.doc
  2. 《撒哈拉的故事》读后感
  3. 求两个多项式相加的和(数据结构cpp)
  4. vue element admin登录方式切换(密码登录或短信登录)
  5. 少儿学python书籍推荐_儿童节,我们从零开始——Python入门资源推荐
  6. Excel 2007打开宏和设计模式等
  7. 2023年前端面试题汇总
  8. box2d 中b2Body的isSensor用法
  9. PS运动鞋案例(记录学习过程)
  10. 汇客huikeCRM项目实战-熟能生巧