本话讲的是Avalonia中相比于WPF更方便的一些特性
布局
布局方面没什么好说的,和WPF没什么区别,Grid,StckPanel...这些,不熟悉的话可以B站上找一下教程
xml树
在WPF中我们是可以在调试的时候显示Xml结构树的,在Avalonia中有些区别,在调试模式下,我们可以按F12调出Devtools,就可以看到Xml结构树了
*
Margin
在Avalonia中,我们有两种方式去给元素更便利的添加Margin
#### 特性
##### 看到Margin,熟悉WPF的小伙伴应该很清楚有时候为了给panel中各种控件写margin的繁琐,现在Avalonia对于布局新出了一个特性,Spacing。
##### 在这里可以看到,我在StackPanel中放了4个Textblock,且没设间距,看起来像只有一个元素一样,在WPF中,我们调整间距的话还得去给每一个子元素添加margin间距,。

##### 但是现在有新特性,直接一句代码就可以搞定。没错,就简简单单的`Spacing="10"`就搞定了每一个元素的间距,再也不用为了调整各种间距而头疼了

#### style
##### 没错,我们还可以使用Style来更方便的给元素添加特性。也许大家会想,WPF中不也可以吗。其实在Avalonia中对于选择器引入了CSS的概念,熟悉前端的小伙伴应该知道,css选择器有很多,可以更加方便的查找符合条件的元素,不说废话,上图,请看下图

###### 这里可以看到,我们定义了一个样式,大家有没有看出区别,没错,在StackPanel上有这么一个属性`Classes="aaa"`,这代表我们可以给这个元素绑定多个属性,和前端用法一样`Classes="class1 class2"`就可以添加多个特性了
###### 在Style上,也看到这么一句话`Selector="StackPanel.aaa TextBlock"`,这句话代表什么呢,也就是这个样式只会作用于StackPanel且带有aaa样式下的所有TextBlock元素。所以,看到这里,其实已经知晓Avalonia中引入了css中的概念,有各种选择器。这可以使我们更加便利的调整自己所需要的样式。
特性
##### Watermark提示文本
###### 在WPF中我们要知道,想要为输入框输入提示文本,要么借助第三方控件库,要么自己自定义控件,但是在Avalonia中,官方自己提供了这个属性,就是Watermark,只需要在textbox上加上这个属性就行
<TextBox Watermark="请输入账号"></TextBox>

###### 可以清除的看到只需要加上这么一个属性就完成了提示文本
##### MaskedTextBox
###### 这个控件我们知道winform中有,wpf中原生是没有的,想要只能自定义,而Avalonia中原生是自带这个控件的
<MaskedTextBox Mask="(+86) ###-####-####"></MaskedTextBox>
###### 只需要这么使用,我们就能得到下图的效果


##### RowDefinitions、ColumnDefinitions
###### 在Wpf中我们定义一个三行三列的栅格布局得这么写
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
###### 但是在Avalonia中我们只需要这么写就可以实现同样的效果,当然,在比较复杂的场景下也可以像上面的写法来写,并不是说只支持下面这种写法,下面这种写法只是在简单场景下更方便我们写布局,不用再去写更多的代码
<Grid RowDefinitions ="*,*,*" ColumnDefinitions="*,*,*"></Grid>
##### 数据绑定
###### 这里简单说一下数据绑定上相对于WPF的便利性
<TextBox Name="txtTelphone" Width="200" Watermark="请输入电话号码"></TextBox>
<TextBlock Text="{Binding #txtTelphone.Text}"></TextBlock>

###### 这里同样可以看到类似于CSS选择器的绑定方式,直接将输入框的文本绑定到textblock上了。
###### 对于数据绑定还有更多便利的使用,请查看官方文档[Avalonia下更方便的数据绑定](https://docs.avaloniaui.net/zh-Hans/docs/guides/data-binding/binding-to-controls "Avalonia下更方便的数据绑定")
##### 响应式事件
###### 这里的响应式事件也就是会监听某个属性的状态来决定某个元素的状态,也就是响应用户交互并触发操作,下面将用一个最简单的例子来讲一下,其效果和前端表单Form的数据验证一样
<TextBox Width="200" Watermark="请输入文本" Text="{Binding InputText}"></TextBox>
<Button Width="100" Content="测试按钮" Command="{Binding ButtonIsEnableCommand}"</Button>
private string _inputText;
public string InputText
{
get => _inputText;
set => this.RaiseAndSetIfChanged(ref _inputText, value);
}
public ReactiveCommand<Unit,Unit> ButtonIsEnableCommand { get; }
public MainWindowViewModel()
{
var buttonIsEnable = this.WhenAnyValue(x=>x.InputText,x=>!string.IsNullOrWhiteSpace(x));
ButtonIsEnableCommand = ReactiveCommand.Create(ButtonIsEnable, buttonIsEnable);
}
private void ButtonIsEnable()
{
}
###### 上面是我们的代码,可以看到我们给文本框绑定了属性,同样也给按钮绑定了事件,这样会有什么效果呢,看下图


###### 可以清楚的看到,在文本框没有输入文本的情况下,按钮是不可点击的状态,且我们并没有设置按钮的的IsEnable属性。这样就完成了响应式事件,对于这种情况,相信很多小伙伴可以想到应用的场景。在某些场景下,我们要根据状态来是否可执行下一步就可以用这个来实现
动画Animation
说到动画,我们更加熟悉的应该是前端了,前端实现动画可以说是最简单了,基于css可以实现很多酷炫好看的动画。
现在在Avalonia中我们也可以像css一样,更好的使用关键帧动画、过渡效果,

