第二章:WPF常用控件介绍
WPF常用控件介绍
前言
总目录
在上一章中,初步的认识了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、ResizeMode
ResizeMode的属性值及其效果如下列表所示:
属性值 | 作用 |
---|---|
NoResize | 窗口大小不可调整,最大化和最小化按钮不显示,只有关闭按钮 |
CanResize | 窗口大小可调整,最大化和最小化按钮都显示并可用 |
CanMinimize | 最小化和最大化按钮显示,但最小化按钮可用,最大化不可用 |
CanResizeWithGrip | 窗口大小可调整,最大化和最小化按钮都显示并可用 |
CanResizeWithGrip 相对于 CanResize 右多了一个“角标” 表示可调整窗体大小
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中对数据文件分为三类:
- 资源文件—被编译进可执行文件exe或者类库dll的数据文件
- 内容文件—与程序集有显式关联关系的独立的数据文件
- 源站点文件—与程序集没有关联的独立数据文件
如下图所示:如果我们将生成操作设置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就是异步执行的,并不是按调用顺序一个个执行,而是无序的异步执行。
总结
总目录
以上就是今天要讲的内容,本文介绍了日常开发过程中经常会使用到的控件,了解这些控件和属性对于我们日后的开发是必不可少的储备知识。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)