Avalonia跟WPF的不同点
avalonia可以说是基于wpf的产物,所以沿袭了大部分wpf写法,但考虑到通用性和跨平台,我们在软件开发时,肯定还是有不同的地方。下面就实际软件开发中,总结的一些不同点。
1.界面上avalonia文件是axaml,不是xaml。另外不能再Resources,所以样式(Styling)上,avalonia支持类似css属性的写法,增加有样式选择器,以提供泛型的标记选中,而不只通过wpf的命名和继承关系来选中。如下指定控件的Classes,并为其设置样式:
<UserControl><UserControl.Styles><!-- 让带有 h1 样式类的 TextBlock 具有 24 点的字体大小 --><Style Selector="TextBlock.h1"><Setter Property="FontSize" Value="24"/></Style></UserControl.Styles><TextBlock Classes="h1">Header</TextBlock>
<UserControl>
2.WPF 中的 UIElement
和 FrameworkElement
是非模板控件的基类,大致对应于 Avalonia 中的 Control
类。WPF 中的 Control
类则是一个模板控件,Avalonia中相应的类是 TemplatedControl
。换种方式表达,对于实际开发中,WPF从 Control
类继承来创建新的模板控件,而在 Avalonia 中从 TemplatedControl
继承;WPF从 FrameworkElement
类继承来创建新的自定义绘制控件,而在Avalonia中从 Control
继承。切换Avalonia思路转换关系:
UIElement
🠞Control
FrameworkElement
🠞Control
Control
🠞TemplatedControl
3.依赖属性方面,可能时因为WPF中的依赖属性基本作用于样式中,所以Avalonia 中与 DependencyProperty
相对应的是StyledProperty
,从名称中看起来更直接。Avalonia 的属性系统比WPF更丰富,还包括 DirectProperty
用于将标准 CLR 属性转换为 Avalonia属性。StyledProperty
和 DirectProperty
的共同基类是 AvaloniaProperty
。
4.跟依赖属性使用场景常常关联的类处理程序方面也有不同,在 WPF 中,可以通过调用 EventManager.RegisterClassHandler 为事件添加类处理程序,示例可能如下:
static MyControl()
{EventManager.RegisterClassHandler(typeof(MyControl), MyEvent, HandleMyEvent));
}private static void HandleMyEvent(object sender, RoutedEventArgs e)
{
}
在 WPF 中,您必须将类处理程序添加为静态方法,而在 Avalonia 中,类处理程序不是静态的:通知会自动定向到正确的实例。在这种情况下,事件处理程序通常的 sender
参数是不必要的,一切保持强类型:
static MyControl()
{MyEvent.AddClassHandler<MyControl>((x, e) => x.HandleMyEvent(e));
}private void HandleMyEvent(RoutedEventArgs e)
{
}
5.更简洁的Grid布局语法。在 Avalonia 中,可以使用字符串来指定列和行定义,例如<Grid ColumnDefinitions="Auto,*,32" RowDefinitions="*,Auto">两行三列的Grid,只需要一行代码,不用定义6行代码来写。另外,我们常在 WPF 中Grid
将两个控件堆叠在一起,在 Avalonia 中则可以直接使用 Panel
,它比 Grid
更轻量级。
6.WPF中,RenderTransforms默认值是 RelativePoint.TopLeft
(0, 0),而对应 Avalonia 中 RenderTransformOrigin 的默认值是 RelativePoint.Center
(中心点),这也不是什么问题,在 AvaloniaUI 中,要获得相同的缩放变换,我们应该指定控件的 RenderTransformOrigin 为控件左上角。
7.针对界面的数据绑定上,WPF不支持x:True和x:Falsec是支持的。例如IsFullScreenButtonVisible="{OnPlatform {x:True}, macOS={x:False}}"属性设置。
8.针对界面元素的可见性UIElement.Visibility / Visibility.Hidden,WPF是支持的,但在Avalonia该特性只部分实现了,并没有完全支持。
9.WPF中没有AutoCompleteBox控件,但在Avalonia中有。WPF中DatePicker控件对应Avalonia中的CalendarDatePicker控件。
10.Avalonia中对不少文档处理控件是不支持的,例如DocumentViewer、 FlowDocumentReader、FlowDocumentPageViewer等等,另外也不支持ListView,就用GridView吧。不支持PrintDialog直接调用打印,毕竟这属于windows系统为此控件的适配。不支持WPF中常用的RichTextBox多文本控件。
11.Avalonia支持RelativePanel,这在WPF中是没有的。想来可能是方便触摸滑动,avalonia支持ScrollContentPresenter,这个在WPF中是没有的。另外其支持TimePicker和TimePickerFlyout,ToggleSwitch切换,这在WPF中也是没有的,算是对wpf的丰富扩展。
12.Avalonia有Panel布局,可以理解成没有行/列的 Grid
,但运行时占用更少的资源。
13.样式的继承,将不同于WPF用BaseOn继承的方式,而是将子样式作为父 <Style>
元素的子元素包含,并在子选择器的开头加上嵌套选择器 ^
<Style Selector="TextBlock.h1"><Setter Property="FontSize" Value="24"/><Setter Property="FontWeight" Value="Bold"/><Style Selector="^:pointerover"><Setter Property="Foreground" Value="Red"/></Style>
</Style>
如上,嵌套样式的选择器将是 TextBlock.h1:pointerover
,这意味着当指针悬停在控件上时,它将显示为红色前景色。相信你也注意到了,这种写法可以不用事件触发器了。
14.avalonia中有点CSS感觉,可以通过Classes定义样式类,例如<Button Classes="h1 blue"/>。还可以通过代码操作样式类,例如control.Classes.Add("blue");
15.avalonia中如果希望控件主题应用于控件的所有实例,需将 {x:Type} 用作资源键。例如: <ControlTheme x:Key="{x:Type Button}" TargetType="Button">。映像中记得wpf不指定样式的key,即可作用于所有同类的TargetType控件,不知道记错了没。