









| 样式选择器 | 描述 |
|---|---|
| Button | 选择所有Button(类)的控件 |
| Button.red | 选择所有带有red样式类的Button控件 |
| Button.red.large | 选择所有同时带有red和large样式类的Button 控件 |
| Button:focus | 选择带有:focus 伪类激活的Button 控件 |
| Button.red.focus | 选择所有同时带有red样式类和 :focus 伪类激活的Button 控件 |
| Button#myButton | 选择Name(属性)为"myButton"的Button 控件 |
| StackPanel Button.x1 | 选择所有带有x1样式类的Button(类)控件,同时他们是StackPanel(类)控件的后代,可以位于任何级别 |
| StackPanel>Button.x1 | 选择所有带有x1样式的Button(类控件),同时他们是StackPanel (类)控件的直接后代 |
| Button/template/ContentPresenter | 选择所有在Button(类)控件的模板内的ContentPresenter(类)控件 |
在Avalonia 中可以在定义样式时,通过样式选择器Selector直接指定到对应的控件,并通过classes进行区分应用不同的样式,和CSS样式类似。在所有控件中增加了一个属性 Classes 用来设置当前控件使用的样式类。
<Grid>
<Grid.Styles>
<!--让带有h1样式类的TextBlock具有24点字体大小-->
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="24" />
</Style>
</Grid.Styles>
<TextBlock Classes="h1" Text="" Foreground="SkyBlue" FontFamily="{StaticResource iconfont}" Width="100" Height="35" />
</Grid>
如果Selector 中只复制了控件类型,而没有“.”向下细分,则样式会应用到所有内部的同类型控件上
样式可以嵌套在其它样式中。要使用嵌套样式,只需将资阳市作为父 Style 元素的子元素包含,并在子选择器的开头加上嵌套选择器^ 即可。pointerover 鼠标悬停触发
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="24" />
<Setter Property="FontWight" Value="Bold" />
<Style Selector="^:pointerover">
<Setter Property="Background" Value="Red" />
<Style>
</Style>
可以为Avalonia UI 控件分配一个或多个样式类,并使用他们来指导样式选择。样式类通过在控件元素中使用Classes属性进行分配,如果使用多个类,则使用空格分隔
<Button Classes="h1 blue" />
也可以通过CS 代码实现:
control.Classes.Add("blue");
control.Classes.Add("red");
如果把样式应用于不同控件,可以用逗号分隔
<Style Selector="TextBlock,Button">
Avalonia 中的伪类,类似与CSS,是由Control(控件)暴露出的关键字,用于方便地知识控件的特定状态,以便于样式选择器使用。这些状态被用于条件性地样式化控件。例如一个Button 在被按下时可以有不同的外观,一个TextBox在被禁用时也是如此。
<StackPanel>
<StackPanel.Styles>
<Style Selector="Button:pressed">
<Settor Property="Foreground" Value="Red" />
</Style>
</StackPanel.Styles>
</StackPanel>
常用伪类
| 伪类 | 描述 |
|---|---|
| :disabled | 控件失效,无法交互 |
| :pointerover | 鼠标悬停 |
| :focus | 获得焦点 |
| :focus-within | 获得焦点或子元素获得焦点 |
| :focus-Visible | 获得焦点并可见 |
自定义伪类:[PseudoClasses(":left",":right",":middle")]
通过 /template/ 可以找到非自定义的控件的内部元素,并更改其样式。
<StackPanel>
<StackPanel.Styles>
<Style Selector="Button:pressed /template/ContentPresenter">
<Setter Property="TextBlock.Foreground" Value="Red" />
</Style>
</StackPanel.Styles>
<Button>Test </Button>
</StackPanel>
<Window>
<Window.Styles>
<StyleInclude Source="/Styles/AppStyle.axaml" />
</Window.Styles>
</Window>
引用其他程序集的样式 avares://
<Application>
<Application.Styles>
<FluentTheme Mode="Light" />
<StyleInclude Source="avares://MyApp.Shared/Styles/CommonAppStyle.axaml" />
</Application.Styles>
</Application>
通过主题字典可以添加多个资源字典,设置不同的键值:Light/Dark
<Application ....
RequestedThemeVariant="Dark">
<Application.Styles>
</Application.Styles>
通过关键字 #TargetControlName.TargetProperty ,而不是WPF中的ElementName="" Path=""
<TextBox Name="other">
<!--绑定到名称伪other控件的Text属性-->
<TextBlock Text="{Binding #other.Text}" />
通过关键字: $parent:TargetProperty 而WPF是通过{Binding RelativeResource={RelativeResource Mode.Self},Path=""} 来实现的
<Border Tag="Hello World">
<TextBlock Text="{Biding $parent.Tag}" />
</Border>
任意父级:$parent[Grade].TargetProperty
<Border Tag="Hello">
<Border>
<TextBlock Text="{Binding $parent[1].Tag}" />
</Border>
</Border>
指定父级类型
$parent[ParentControlType].TargetProperty
<Border Tag="Hello World!">
<Decorator>
<TextBlock Text="{Binding $parent[Border].Tag}" />
</Decorator>
</Border>
指定类别和级别:$parent[ParentControlType;Grade].TargetProperty
<Border Tag="Hello World">
<Border>
<Decorator>
<TextBlock Text="Binding $parent[Border;1].Tag" />
</Decorator>
</Border>
</Border>
第三方控件:$parent[AssemblyName:ParentControlType].TargetProperty
<local:MyControl Tag="Hello World!">
<Decorator>
<TextBlock Text="{Binding $parent[local:MyControl].Tag}" />
</Decorator>
</local:MyControl>
Avalonia UI 数据绑定提供了一种使用命名约定来实现“能否执行”功能的简单方法。
如果你需要根据命令参数或视图模型属性的值来决定是否执行,那么你可以编写一个第二个布尔方法来检查操作方法是否可以执行
为了使其工作,Avalonia UI使用了布尔方法与操作方法相同的根方法名,但加上了前缀Can的命名约定。
public class MainViewModel
{
publci void PerformAction(object msg)
{
Debug.WriteLine("$The action was called.{msg}");
}
}
AXAML
<StackPanel Margin="20">
<TextBlock Margin="0 5" x:Name="message" WaterMark="添加一条消息" />
<Button Command="{Binding PerformAction}" CommandParameter="{Binding #message.Text}" >
Run the example
</Button>
</StackPanel>
如果需要进行一些繁重的工作来加载属性内容,可以绑定到async Task的结果
public Task<string> MyAsyncText=GetTextAsync();
private async Task<string> GetTextasync()
{
await Task.Delay(1000);
return "Hello from async operation";
}
AXAML
<TextBlock Text="{Binding MyAsyncText^,FallbackValue='wait a second'}" />
对于需要延迟返回的任务结果需要加绑定后缀:^
Iteration可设置伪指定次数或无限循环
<Window xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaMVVMDemo.Window1"
Title="动画" WindowStartupLocation="CenterScreen">
<Window.Styles>
<!--在样式中使用动画,Avalonia中动画是通过关键帧来设置的,样式中的关键帧Style.Animations 可设置多个动画-->
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red" />
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="INFINITE">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
<Setter Property="RotateTransform.Angle" Value="90.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
<TabControl>
<TabItem Header="动画1">
<Grid RowDefinitions="Auto,*">
<StackPanel Orientation="Horizontal">
<TextBlock Text="样式中的关键帧动画,IterationCount 可设置伪指定次数或无限循环" />
</StackPanel>
<Rectangle Classes="red" Height="50" Width="50" Grid.Row="1" />
</Grid>
</TabItem>
</TabControl>
</Window>
PlaybackDirection="AlternateReverse"
| 值 | 描述 |
|---|---|
| Normal | (默认)正向播放动画 |
| Reverse | 反向播放动画 |
| Alternate | 先正向播放动画,然后反向播放 |
| AlternateReverse | 先反向播放动画,然后正向播放 |
| 值 | 描述 |
|---|---|
| None | 动画运行后,值不会保留,也不会在动画延迟时应用第一个值 |
| Forward | 最后的插值值将持续保留到目标属性 |
| Backward | 在动画延迟时,第一个插值值将显示 |
| Both | 将同时应用Forward和Backward行为 |
<Window xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaMVVMDemo.Window1"
Title="动画" WindowStartupLocation="CenterScreen">
<Window.Styles>
<!--在样式中使用动画,Avalonia中动画是通过关键帧来设置的,样式中的关键帧Style.Animations 可设置多个动画-->
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red" />
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="INFINITE" PlaybackDirection="Reverse">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
<Setter Property="RotateTransform.Angle" Value="90.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
<TabControl>
<TabItem Header="动画1">
<Grid RowDefinitions="Auto,*">
<StackPanel Orientation="Horizontal">
<TextBlock Text="样式中的关键帧动画,IterationCount 可设置伪指定次数或无限循环" />
</StackPanel>
<Rectangle Classes="red" Height="50" Width="50" Grid.Row="1" />
</Grid>
</TabItem>
<TabItem Header="填充模式">
<Grid RowDefinitions="*,*,*">
<TextBlock Text="None" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="Forward" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Backward/Delay" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle Grid.Row="0" Height="100" Width="5">
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Red" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="None">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0.0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
<Rectangle Grid.Row="1" Height="100" Width="5" >
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Blue" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="Forward">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
<Rectangle Grid.Row="2" Height="100" Width="5">
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Green" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="Backward" Delay="0:0:3">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
</Grid>
</TabItem>
</TabControl>
</Window>
Easing="BounceEaseIn"
<Window xmlns="https://github.com/avaloniaui"
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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaMVVMDemo.Window1"
Title="动画" WindowStartupLocation="CenterScreen">
<Window.Styles>
<!--在样式中使用动画,Avalonia中动画是通过关键帧来设置的,样式中的关键帧Style.Animations 可设置多个动画-->
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red" />
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="INFINITE" PlaybackDirection="Reverse">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
<Setter Property="RotateTransform.Angle" Value="90.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
<TabControl>
<TabItem Header="动画1">
<Grid RowDefinitions="Auto,*">
<StackPanel Orientation="Horizontal">
<TextBlock Text="样式中的关键帧动画,IterationCount 可设置伪指定次数或无限循环" />
</StackPanel>
<Rectangle Classes="red" Height="50" Width="50" Grid.Row="1" />
</Grid>
</TabItem>
<TabItem Header="填充模式">
<Grid RowDefinitions="*,*,*" ColumnDefinitions="*,*">
<TextBlock Text="None" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock Text="Forward" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Backward/Delay" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Rectangle Grid.Row="0" Height="100" Width="5">
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Red" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="None">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0.0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360.0" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
<Rectangle Grid.Row="1" Height="100" Width="5" >
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Blue" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="Forward">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
<Rectangle Grid.Row="2" Height="100" Width="5">
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Green" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" FillMode="Backward" Delay="0:0:3">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
<Border Grid.Row="0" Grid.Column="1" Width="35" BorderBrush="AliceBlue" BorderThickness="1">
<Rectangle VerticalAlignment="Bottom">
<Rectangle.Styles>
<Style Selector="Rectangle">
<Setter Property="Fill" Value="Blue" />
<Setter Property="Height" Value="0" />
<Style.Animations>
<Animation Duration="0:0:5" IterationCount="Infinite" Easing="BounceEaseOut">
<KeyFrame Cue="0%">
<Setter Property="Height" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Height" Value="150" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Rectangle.Styles>
</Rectangle>
</Border>
</Grid>
</TabItem>
</TabControl>
</Window>
Avalonia中的过度效果也受CSS动画的很大启发。它们监听目标属性值的任何变化,并根据其参数对变化进行动画处理。可以通过Transitions属性在任何Control上定义过度效果.
<TabItem Header="过度效果Transition">
<Grid RowDefinitions="*,*" ColumnDefinitions="*,*" ShowGridLines="True">
<Grid.Styles>
<Style Selector="Rectangle.h1">
<Setter Property="Height" Value="200" />
<Setter Property="Width" Value="100" />
<Setter Property="Fill" Value="Red" />
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style Selector="Rectangle.h1:pointerover">
<Setter Property="Opacity" Value="1" />
</Style>
</Grid.Styles>
<Rectangle Classes="h1" >
<Rectangle.Transitions>
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.5" />
</Transitions>
</Rectangle.Transitions>
</Rectangle>
</Grid>
</TabItem>
每个过度效果都有Property、Delay、Duration和可选的Easing 属性
Property 表示过度效果的目标属性,用于监听和动画处理值
Delay 表示过度效果应用于目标之前的等待时间
Duration 表示过度效果播放的时间长度
缓动函数于关键帧动画中描述相同
以下是可用的过度效果类型。必须根据要动画处理的属性类型选择正确的类型。
在指针悬停其上方时旋转45度
| 过度效果 | 示例 | 可接受的单位 |
|---|---|---|
| translate | translate(10px),translate(0px,10px) | px |
| translateX | translateX(10px) | px |
| translateY | translateY(10px) | px |
| scale | scale(10),scale(0,10) | |
| scaleX | scaleX(10) | |
| scaleY | scaleY(10) | |
| skew | skew(90deg,skew(0,90deg)) | deg,grad,rad,turn |
| skewX | skewX(90deg) | deg,grad,rad,turn |
| skewY | skewY(90deg) | deg,grad,rad,turn |
| rotate | rotate(90deg) | deg,grad,rad,turn |
| matrix | matrix(1,2,3,4,5,6) |
TransitioningContentControl 可以使用页面过度来对内部控件上的内容更改进行动画处理
| Content | 要在控件中显示的内容 |
|---|---|
| TransitioningContentControl.ContentTemplate | 用于显示内容的数据模板 |
| TransitioningContentControl.PageTransition | 用于对内容更改进行动画处理的页面过度效果。应用的主题将提供默认页面过渡。要禁用转换,请将此属性设置伪null |
页面过度动画
CrossFade(默认):跨但如淡出页面过度通过动画方式改变不透明度,从而使当前页面淡出,新页面淡入。
PageSlid:页面滑动过度将旧页面移除视图,并将新页面视图移入。可以使用Orientation属性指定滑动方向(默认为水平)
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。