WPF復(fù)習(xí)知識(shí)點(diǎn)記錄
由于近幾年主要在做Web項(xiàng)目,客戶端的項(xiàng)目主要是以維護(hù)為主,感覺對(duì)于基礎(chǔ)知識(shí)的掌握沒有那么牢靠,趁著這個(gè)周末重新復(fù)習(xí)下WPF的相關(guān)知識(shí)。
文章內(nèi)容主要來自大佬劉鐵錳老師的經(jīng)典著作《深入淺出WPF》。
因?yàn)槭菑?fù)習(xí),所以知識(shí)內(nèi)容不會(huì)一一記錄,如有需要了解更多可以看書中內(nèi)容。
注意:博客中的代碼示例我是以avalonia為UI框架寫的。代碼可能部分跟WPF的稍有不同。
1.從零起步認(rèn)識(shí)XAML
1.什么是XAML
XAML(讀作zaml)是WPF技術(shù)中專門用于設(shè)計(jì)UI 的語(yǔ)言
2.優(yōu)點(diǎn)
- 實(shí)現(xiàn)界面與代碼的分離
- 可以設(shè)計(jì)出專業(yè)的UI和動(dòng)畫
- 基于XML的標(biāo)記語(yǔ)言,簡(jiǎn)單易懂,結(jié)構(gòu)清晰
3.XAML剖析
1.最簡(jiǎn)單的XAML代碼
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
</Window>
這個(gè)示例中,Window
是一個(gè)XAML元素,它表示窗口組件。xmlns
屬性定義了XML命名空間,即指明XAML所使用的命名空間。在這里,http://schemas.microsoft.com/winfx/2006/xaml/presentation
是WPF的命名空間。
這個(gè)示例中的XAML代碼只有一個(gè)Window
元素,它是一個(gè)空的容器??梢栽?code>Window元素中添加其他界面元素,例如按鈕、文本框等,來構(gòu)建應(yīng)用程序的用戶界面。同樣,可以在XAML中設(shè)置屬性來更改元素的外觀和行為。
2.property和attribute
先不說WPF中兩個(gè)屬性的定義,我們先看看對(duì)應(yīng)一個(gè)類的對(duì)象。
1)屬性是指類體里用get或set封裝好的屬性。屬性是面向?qū)ο蟮睦碚摲懂?。比如說一個(gè)盒子,盒子的高度,長(zhǎng)度,都是這個(gè)盒子的屬性。在C#中實(shí)現(xiàn)的時(shí)候可以通過GET SET 封裝。
2)特性是指應(yīng)用于類,字段,方法,接口的進(jìn)一步說明,用專業(yè)的術(shù)語(yǔ)就是給類,字段,方法,接口補(bǔ)充元數(shù)據(jù),說的再白一點(diǎn)就是給它們打上標(biāo)記,打了標(biāo)記后編譯器就知道如何來編譯它。特性是屬于編程語(yǔ)言層面的東西。比如2個(gè)相同的類,為了表示這2個(gè)類不完全相同或者有差異。這時(shí)候就要針對(duì)這兩個(gè)類加一些特性。
[Serializable] // 這是Attribute,打上該標(biāo)記的類說明可以被序列化
class Order
{
protected internal Single Price { get; set; } // 這是Property
[Obsolete("此方法已過時(shí),請(qǐng)改用xxx.")] // 打上該標(biāo)記說明此方法是過時(shí)的
public Single GetPrice()
{
return default(Single);
}
}
在看在XAML中:
Attribute 在XAML中的對(duì)于標(biāo)簽的屬性特征,以下都是Window標(biāo)簽下的attribute
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaMarkdown.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaMarkdown.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
xmlns:md="clr-namespace:Markdown.Avalonia;assembly=Markdown.Avalonia"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaMarkdown"
Property 在后臺(tái)代碼中針對(duì)對(duì)象的屬性特征,對(duì)應(yīng)的后端類的對(duì)象Text,就是一個(gè) property:
private string _text="hello";
public string Text
{
get => _text;
set => this.RaiseAndSetIfChanged(ref _text, value);
}
private string _filePath;
3.xmlns 名稱空間
xmlns[:可選的映射前綴]="名稱空間"
用于引用外來程序集
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaMarkdown.ViewModels"
沒有映射前綴的是默認(rèn)名稱空間,默認(rèn)名稱空間只能有一個(gè)。
通過xmlns,我們可以直接使用這些CLR名稱空間中的類型
4.partial關(guān)鍵字
XAML文件對(duì)應(yīng)的.xaml.cs文件中的類的聲明使用了partial關(guān)鍵字,可以把一個(gè)類拆分在多處定義,只要各部分代碼不沖突即可,由于partial機(jī)制,我們實(shí)現(xiàn)邏輯代碼留在.cs文件中,把UI元素相關(guān)代碼分離出去。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
2.XAML語(yǔ)法
1.樹形結(jié)構(gòu)
<Window>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<Button>打開</Button>
<Button>保存</Button>
<Label/>
</StackPanel>
</Grid>
<TextBox Grid.Row="1" Grid.Column="0"/>
<md:MarkdownScrollViewer Grid.Row="1"
Grid.Column="1"/>
</Grid>
</Window>
XAML UI 框架是樹狀結(jié)構(gòu),以
2.x:Name
x:Name的作用:
- 告訴XAML編譯器,帶有x:Name的標(biāo)簽需要聲明一個(gè)引用變量,變量名就是x:Name的值
- 將XAML標(biāo)簽對(duì)應(yīng)的對(duì)象的Name屬性也設(shè)為x:Name的值,并注冊(cè)到UI樹上,方便查找
2.x:Key
在資源字典(Resource Dictionary)中使用,構(gòu)成其中的元素。資源(Resource )非常重要,存放需要重復(fù)使用的內(nèi)容。
<Application.Resources>
<Color x:Key="SystemAccentColor">rgb(155, 138, 255)</Color>
<Color x:Key="SystemAccentColorDark1">rgb(155, 138, 255)</Color>
<Color x:Key="SystemAltMediumLowColor">rgb(52, 53, 65)</Color>
<Color x:Key="ApplicationPageBackgroundThemeBrush">rgb(52, 53, 65)</Color>
<Color x:Key="ControlStrokeColorDefaultBrush">rgb(94, 95, 109)</Color>
</Application.Resources>
3.控件
1.ContentControl 單一內(nèi)容控件
只能單一元素充當(dāng)其內(nèi)容。
例如:Button、Label等(具體看書中列表)
2.HeaderdContentControl
除了用于顯示主體內(nèi)容的區(qū)域外,控件還具有一個(gè)顯示標(biāo)題(header)的區(qū)域
例如:GroupBox、TabItem
3.ItemsControl
- 顯示列表化的數(shù)據(jù)
- 內(nèi)容屬性為Items或ItemsSource
- 每種ItemsControl都對(duì)應(yīng)有自己的條目容器(Item Container)
例如:ListBox、TreeView
4.Decorator
在UI 上起裝飾效果,比如可以使用Border元素為一些組織在一起的內(nèi)容加個(gè)邊框
例如:Border、ViewBox
5.TextBlock和TextBox
最常用的文本控件
- TextBlock 用于顯示文本,不能編輯
- TextBox 允許編輯內(nèi)容
6.Shape
繪制圖形使用的元素
- Fill 屬性設(shè)置填充
- Stroke 屬性設(shè)置邊線
7.Panel
所有的UI布局元素都屬于這一族
Panel元素控制布局
包括:Canvas、Grid、StackPanel等
4.布局
WPF的UI形成的樹形結(jié)構(gòu),我們稱之為可視化樹(Visual Tree)
控件框架形成的樹形結(jié)構(gòu),我們稱之為邏輯樹(Logic Tree)
五種大類
- Grid 網(wǎng)格面板
- DockPanel 停靠面板
- StackPanel 棧面板
- WrapPanel 環(huán)繞面板
- Canvas 精準(zhǔn)定位
下面復(fù)習(xí)下它們的使用方法:
1.Grid
網(wǎng)格形式布局
1.CloumnDefinitions
定義多少列
2.RowDefinitions
定義了多少行
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="small" Margin="0,0,20,0" Command="{Binding UploadCommand}">打開</Button>
<Button Classes="small" Margin="0,0,20,0" Command="{Binding SaveCommand}">保存</Button>
<Label Content="{Binding FilePath}" Margin="0,0,20,0"/>
</StackPanel>
</Grid>
3.Grid長(zhǎng)寬常用設(shè)置值
- 絕對(duì)值:double 數(shù)值后加單位后綴
- 比例值:double數(shù)值后加一個(gè)星號(hào)(*)(如上例)
- 自動(dòng)值:Auto
2.StackPanel
StackPanel可以把內(nèi)部的元素在縱向或橫向上緊湊排列,形成棧式布局
適合場(chǎng)合:
- 同類元素需要緊湊排列(列表或菜單)
- 移除其中的元素后能夠自動(dòng)補(bǔ)缺的布局或者動(dòng)畫
1.屬性
常用屬性 | 數(shù)據(jù)類型 | 可選值 | 說明 |
---|---|---|---|
Orientation | Orientation | Horizontal(水平排列)\Vertical(垂直排列) | 決定內(nèi)部元素是水平還是垂直排列,默認(rèn)值(Vertical) |
Background | Brush | 背景色(Red/Yellow等等) | |
HorizontalAlignment | HorizontalAlignment | Center(中心)/Left(靠左)/Right(靠右)/Stretch(拉伸以填充父元素) | 決定內(nèi)部元素在水平方向的對(duì)齊方式 |
VerticalAlignment | VerticalAlignment | Top(上方)/Center(中心)/Bottom(下方)/Stretch(拉伸以填充父元素) | 決定內(nèi)部元素在垂直方向的對(duì)齊方式 |
3.Canvas
畫布,可以使用Left、Top、Right、 Bottom。內(nèi)部元素通過離上下左右的距離控制元素在布局中的位置。
4.DockPanel
DockPanel會(huì)對(duì)每個(gè)子元素進(jìn)行排序,并??吭诿姘宓囊粋?cè),多個(gè)??吭谕瑐?cè)的元素則按順序排序,。
<Grid>
<DockPanel Width="Auto" Height="Auto">
<Button DockPanel.Dock="Left" >1</Button>
<Button DockPanel.Dock="Top">2</Button>
<Button DockPanel.Dock="Right">3</Button>
<Button DockPanel.Dock="Bottom">4</Button>
</DockPanel>
</Grid>
5.WrapPanel
流式布局,根據(jù)
Orientation
屬性來設(shè)置其水平或垂直布局方向
默認(rèn)是水平排列
<WrapPanel>
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
</WrapPanel>
垂直排列
<WrapPanel Orientation="Vertical">
</WrapPanel>
5.Binding 綁定
數(shù)據(jù)交互核心屬性,在字段定義的set語(yǔ)句中使用一個(gè)PropertyChanged事件,,當(dāng)為Binding設(shè)置了數(shù)據(jù)源后,就會(huì)自動(dòng)偵聽PropertyChanged事件
WPF
using CommunityToolkit.Mvvm
private string _searchKeyword;
public string SearchKeyword
{
get => _searchKeyword;
set => SetProperty(ref _searchKeyword, value);
}
Avalonia
using ReactiveUI;
private string _filePath;
public string FilePath
{
get => _filePath;
set => this.RaiseAndSetIfChanged(ref _filePath, value);
}
6.Dependency Property 依賴屬性
依賴屬性是一種本身沒有可以沒有值,能通過使用Binding從數(shù)據(jù)源獲取值的屬性。擁有依賴屬性的對(duì)象稱為“依賴對(duì)象”。
特點(diǎn)包括:
- 節(jié)省實(shí)例對(duì)內(nèi)存的開銷
- 屬性值可以通過Binding依賴在其他的對(duì)象上
7.Attached Property 附加屬性
附加屬性,被環(huán)境賦予的屬性,作用是將屬性與數(shù)據(jù)類型(宿主)解耦,讓數(shù)據(jù)類型的設(shè)計(jì)更加靈活
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="10*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="10*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<Button>打開</Button>
<Button>保存</Button>
<Label/>
</StackPanel>
</Grid>
<TextBox Grid.Row="1" Grid.Column="0"/>
<md:MarkdownScrollViewer Grid.Row="1"
Grid.Column="1"/>
</Grid>
上面 TextBox 的Grid.Row,Grid.Column都是附加屬性。
8.Route 和Event 路由事件
路由事件被激發(fā)后是沿著Visual Tree傳遞的,只有這樣,“藏”在Templete里的控件才能把消息送出來。
9.Resource 資源
每個(gè)WPF的界面的元素都具有一個(gè)名為Resources的屬性,這個(gè)屬性繼承自FrameWorkElement類,其類型為ResourceDictionary,用來存儲(chǔ)資源。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="/Assets/Lang/en-US.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
在使用資源時(shí)候分為靜態(tài)資源(StaticResource)和動(dòng)態(tài)資源(DynamicResource)
1.StaticResource
在程序載入內(nèi)存時(shí)對(duì)資源一次性使用,之后就不再去訪問這個(gè)資源了
<TextBox Grid.Row="4"
Name="Editor3"
AcceptsReturn="True"
Text="{Binding Source={StaticResource VMLocator}, Path=EditorViewModel.Editor3Text,Mode=TwoWay}"
FontSize="{Binding Source={StaticResource VMLocator}, Path=EditorViewModel.EditorCommonFontSize}" />
2.StaticResource
程序運(yùn)行過程中仍然會(huì)去訪問資源
<Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2"
Grid.Row="2" />
10.Template 模板
1.ControlTemplate 控制器模板
<ControlTemplate>
<Border Name="DataGridBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,*,Auto,Auto">
<DataGridColumnHeader Name="PART_TopLeftCornerHeader"
Theme="{StaticResource DataGridTopLeftColumnHeader}" />
<DataGridColumnHeadersPresenter Name="PART_ColumnHeadersPresenter"
Grid.Column="1"
Grid.Row="0" Grid.ColumnSpan="2" />
<Rectangle Name="PART_ColumnHeadersAndRowsSeparator"
Grid.Row="0" Grid.ColumnSpan="3" Grid.Column="0"
VerticalAlignment="Bottom"
Height="1"
Fill="{DynamicResource DataGridGridLinesBrush}" />
<DataGridRowsPresenter Name="PART_RowsPresenter"
Grid.Row="1"
Grid.RowSpan="2"
Grid.ColumnSpan="3" Grid.Column="0">
<DataGridRowsPresenter.GestureRecognizers>
<ScrollGestureRecognizer CanHorizontallyScroll="True" CanVerticallyScroll="True" />
</DataGridRowsPresenter.GestureRecognizers>
</DataGridRowsPresenter>
<Rectangle Name="PART_BottomRightCorner"
Fill="{DynamicResource DataGridScrollBarsSeparatorBackground}"
Grid.Column="2"
Grid.Row="2" />
<Image Source="/Assets/maskGrad.png"
Grid.Row="1" Grid.RowSpan="2" Grid.Column="0" Grid.ColumnSpan="4"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"
Width="60"
Stretch="Fill"
IsHitTestVisible="False"
ZIndex="1" />
<ScrollBar Name="PART_VerticalScrollbar"
Orientation="Vertical"
Grid.Column="2"
Grid.Row="1"
Width="{DynamicResource ScrollBarSize}"
ZIndex="2" />
<Grid Grid.Column="1"
Grid.Row="2"
ColumnDefinitions="Auto,*">
<Rectangle Name="PART_FrozenColumnScrollBarSpacer" />
<ScrollBar Name="PART_HorizontalScrollbar"
Grid.Column="1"
Orientation="Horizontal"
Height="{DynamicResource ScrollBarSize}" />
</Grid>
<Border Name="PART_DisabledVisualElement"
Grid.ColumnSpan="3" Grid.Column="0"
Grid.Row="0" Grid.RowSpan="4"
IsHitTestVisible="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
CornerRadius="2"
Background="{DynamicResource DataGridDisabledVisualElementBackground}"
IsVisible="{Binding !$parent[DataGrid].IsEnabled}" />
</Grid>
</Border>
</ControlTemplate>
2.DataTemplate 數(shù)據(jù)模板
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
11.Style 風(fēng)格
設(shè)計(jì)外觀和行為動(dòng)作
1.Setter 設(shè)置器
Setter 類的Property屬性用來指明你想為目標(biāo)的哪個(gè)屬性賦值,Value屬性則是你提供的屬性值
<Style Selector="Grid Button">
<Setter Property="BorderBrush" Value="rgb(94, 95, 109)" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Padding" Value="10,0,10,2" />
<Setter Property="Height" Value="32" />
<Setter Property="CornerRadius" Value="6" />
<Setter Property="Margin" Value="0" />
<Setter Property="FontFamily" Value="avares://TmCGPTD/Assets/Lato-Regular.ttf#Lato" />
<Setter Property="Transitions">
<Transitions>
<BrushTransition Property="Background" Duration="0:0:0.2" />
</Transitions>
</Setter>
</Style>
上面的例子是針對(duì) Grid Button的Style,使用了若干個(gè)Setter 來設(shè)置 Grid 中的Button的一些屬性,這樣,在程序中, Grid 中的Button就會(huì)具有統(tǒng)一的風(fēng)格。
2.Trigger 觸發(fā)器
當(dāng)條件滿足時(shí)會(huì)觸發(fā)一個(gè)行為。文章來源:http://www.zghlxwxcb.cn/news/detail-514940.html
<Grid>
<TextBlock Text="raokun" Width="75" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="blue" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
上面的例子,是當(dāng)鼠標(biāo)移動(dòng)在上面時(shí),字體的顏色變成藍(lán)色。文章來源地址http://www.zghlxwxcb.cn/news/detail-514940.html
閱讀如遇樣式問題,請(qǐng)前往個(gè)人博客瀏覽: https://www.raokun.top
擁抱ChatGPT:https://ai.terramours.site
開源項(xiàng)目地址:https://github.com/firstsaofan/TerraMours
到了這里,關(guān)于WPF復(fù)習(xí)知識(shí)點(diǎn)記錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!