如何评价 .NET 平台的跨平台 UI 库 Avalonia UI?

Avalonia UI是一个基于WPF XAML的跨平台UI框架,并支持多种操作系统(Windows(.NET Framework,.NET Core…
关注者
104
被浏览
312,337

13 个回答

很多年前就留意到Avalonia了,但是测试过觉得不太稳定,但一直没用。最近因为有一个WPF的项目想在触摸屏上运行,但是WPF在触摸屏上运行糟糕得很,于是考虑兼容触摸的同时顺便跨平台到LINUX上。

我使用的是11.0.0 Preview6,很多人都觉得Preview版坑……但我觉得对于Avalonia的话……Preview版的坑更小些……在这里说明下,以下我测试的都是在Windows平台上的,Linux还没测试。不是说不试LINUX,WINDOWS都没弄好,搞什么LINUX怀疑人生……

1、中文兼容的问题

其他评论很多人多在骂中文适配的问题,至少现在11.0.0 Preview5是修复了这个问题了,有图为证:


PS: Preview5是修复了这个BUG……然后Preview6又继续无法使用输入法来录入中文了……接着反馈给官方,官方让我测试最新的NightlyBuild(就是比Preview版还新的未发布版本),我测试过11.0.999-cibuild0032725-beta,这个BUG又被修复了……

2、跨平台的特色

现在.NET系跨平台的除了MAUI和Avalonia以外,其实还有个UNOPLATFORM,MAUI就不说了,Avalonia的语法是比较适合WPF开发者的,UNOPLATFORM是比较适合UWP开发者的(网上看到过说UNO的语法故意偏UWP本来是等着给巨硬收购的,可谁知道巨硬不鸟丫的自己搞了MAUI)。

另外Avalonia和.NET系其他跨平台不同,全平台都是用SKIASHARP来渲染,不存在某个平台用WINUI,某个平台用原生,导致不同平台渲染会出现差别的问题发生。

虽然加起来不一定能划等号,但Avalonia就是.NET 版的FLUTTER,同样用的都是SKIA。但Avalonia重视的是WINDOWS、LINUX、MAC这种偏桌面端的跨平台,IOS、ANDROID这样的移动端跨平台虽然也有弄但还是起步阶段。倒过来FLUTTER重视移动端跨平台,桌面端反而落后了。不过FLUTTER后面说会把渲染引擎从SKIA改成Impeller,所以两者更不能完全划等号,只能是一个参考了。

3、国内的大佬

国内搞Avalonia的人好像很少,不过有个叫DONGBIN的哥们,搞了个Semi.Avalonia,Avalonia官方挺推荐他,和Avalonia官方走得很近,貌似也是Avalonia代码的贡献者之一。看他推特上写自己所在城市是上海,应该不是国外华人那种。

PS:DONGBIN大佬本尊出现在知乎了 @兔基 ,有Avalonia的问题和BUG,围他……

当然如果你英文好的话,有使用或者技术上的问题可以去AvaloniaGITHUB的讨论区 AvaloniaUI/Avalonia · Discussions 问,几个Maintainer都会很热情地下场回答你的问题,DONGBIN大佬也经常出现在那里。


4、语法上的优点

Avalonia还有个好处是加入了CSS选择器的语法,甚至动画里面还加上了类似CSS里面的transition,用起来的话简单很多,就是爽。

还有就是其他一些老控件的优化,譬如TextBlock添加了字距、行距的属性,TextBox添加了水印提示等等一下功能。

像以前WPF写Grid设置行列得这样的:

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
</Grid>

但在AVALONIA里面只需要这样:

<Grid RowDefinitions="Auto,Auto,*,40" ColumnDefinitions="Auto,300">
</Grid>

还有很多好玩的东西,都可以看看他们官网的文档: Getting Started - Avalonia UI


5、Avalonia的缺点

和IDE适配不是太好,我用的是VS 2022,Avalonia的扩展用的都是最新。有时候你代码写错了,编译的时候只提示XAML出错什么,你要想知道实际错误,只能重启VS再编译一次才会提示确切是什么错误。

而且经常有奇怪的BUG,不过这些奇怪的BUG大部分Maintainer都能教你用另外的办法绕过去(牛逼)……

有一个也不能说是坑,只是发布新版本的速度真的很慢

类似的UNO PLATFORM 已经发布了2023年第二个更新,但是Avalonia距离上一次更新已经是5个还是6个月了,而且这次更新还是PREVIEW版的,正式版已经没更新一年多了……据说PREVIEW6下一个就是RC版……

上个月看Avalonia官方推特才说Avalonia走马上任了一位CEO,不清楚之前有没有CEO之类的,只是感觉这个项目才刚开始进入规范化的管理,距离UNO PLATFORM那样的还有一定距离。


6、原生AOT

不过需要手动在CSOJ文件里面改成是.NET 7和改成AOT才能用。试过用ILSPY反编译是反编译不了的。

7、开发时候踩过的坑(持续更新)

1、尺寸绑定问题

以前在WPF如果要把A控件的高度绑定为B控件的高度,那么只需要{Binding ActualHeight,ElementName=B}这样就行了。但是在Avalonia是不报错,但也没任何作用的。正确的绑定方法应该是{Binding #B.Bounds.Height}……井号B那个只是Avalonia里面引用的简写,重点是Bound.Height那个……

我是搞不懂为什么ActualHeight绑不了但是又留着ActualHeight还另外搞了个Bounds.Height出来……

2、没有WPF里面Effect的属性

以前在WPF里面可以这样玩

<Ellipse Width="100" Height="100" Fill="Blue"> <Ellipse.Effect> <BlurEffect Radius="5"/> </Ellipse.Effect> </Ellipse>

但是在Avalonia就不行了……人家压根没这个。你要么自己用SkiaSharp搞,要么转成PNG或者其他东西。

人家Maintainer也直白说了,要么你捐赠我们,我们专门给你写一个……嘿嘿嘿……

3、SVG图形不支持半透明或者半透明相关动画

这个没啥好说的……官方推搪说是官方所推荐的那个SVG库作者的问题,SVG库作者推搪是官方的问题,反正不知道是谁问题……

4、Transition和Style联动有BUG

<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="AvaloniaApplication1.MainWindow"
        Title="AvaloniaApplication1">
	<Window.Styles>
		<Style Selector="Border.TestChecked">
			<Setter Property="Height" Value="150"/>
		</Style>
		<Style Selector="Border.TestUnChecked">
			<Setter Property="Height" Value="0"/>
		</Style>
	</Window.Styles>
	<Grid RowDefinitions="auto,auto">
		<CheckBox Name="CB"></CheckBox>
		<Border Width="100" HorizontalAlignment="Left" Background="Red" Classes.TestChecked="{Binding #CB.IsChecked}" Classes.TestUnChecked="{Binding !#CB.IsChecked}" Grid.Row="1">
			<Border.Transitions>
				<Transitions>
					<DoubleTransition Property="Height" Duration="0:0:0.5"></DoubleTransition>