官网:
源码:
https://github.com/AvaloniaUI/Avalonia
讨论版:
https://gitter.im/AvaloniaUI/Avalonia
最近因为要研究跨平台开发,不可避免地顺带了解了Linux系统,把联想平板电脑装成了Ubuntu 20.04系统。
就像Linux系统一样,目前对它的了解是,将就着能用,但不是很好用。期间会遇到奇奇怪怪的各种小问题。
就像我的平板,外接的键盘带触摸板。因为打字的时候很容易触碰到触摸板,所以想把它禁用掉。但是这个在Windows系统很容易解决的小问题,可是在Linux下面可能根本无法解决,或者无法找到解决的方法。
但是这种小问题,其实又是非常影响平常的使用体验的。
这几天,把原来在Windows平板上用WPF开发的一些小程序都移植成了Avalonia版本。几个应用折腾下来,感觉还行,做东西还算是方便的,虽然跟WPF比可能还是有很大差距。
本身因为还没有正式发布,所以肯定还会存在一些问题。
但开发过程中遇到的很多问题,其实很多都是对Avalonia平台和Linux操作系统不是很熟悉。
就像游戏打怪一样,WPF换到了Avalonia,一些经验需要重新积累,其实还是需要几个项目做下来,慢慢地知道了哪些能做,哪些不能做。然后慢慢地扩展功能,积累新经验。
最关键的是,.net平台的跨平台开发,除了Avalonia之外,也没有更好的选择。作为用惯了WPF开发的码农来说,Avalonia应该是目前能找到的最好的代替品。
这几天都是在Ubuntu上用Rider来开发,比VS Code应该要好用一点,但是Rider的很多操作都跟VS不一样,也是一个慢慢熟悉的过程。
网上能找到的资料不多,但是很保贵。初次接触这个平台可以先看一下官网的帮助文档。
遇到问题,我一般会去项目的Github的issues搜索一下,可能会有线索。
剩下的百度谷歌,各种想办法。
再不行,看Avalonia的源码,看能不能解决。
目前不支持的功能
- 托盘图标
- 没有ToolBar功能
- 不支持全局热键
- 不支持在前面XAML界面注册事件
目前遇到无法解决的问题
- 在部分机子上,打开OpenFileDialog时,会卡UI,软件无响应。
- TextBox中 制表符显示乱码的问题,目前还不知道怎么解决。
一些缺点
- 生成的软件包会比较大,因为要带个各个系统的各种类库。
编辑器推荐
- Visual Studio 2019
需要安装一个插件,但是XAML界面下,代码提示功能比较弱,基本上算没有,写起来不是很方便。
- JetBrains Rider
目前最新版本是2021版本,本身是商用,可以试用30天。XAML的编辑提示功能会比VS2019要好,不过代码调试有时候没VS2019方便,可以两个IDE结合起来使用。
如果是在Linux系统下开发,因为没有VS编译器可用,感觉JetBrains Rider会是最好的选择,相比较VS Code,集成度会更高,代码提示等方面都会做得更好一点。
系统测试情况
目前试了一下,能够正常运行的系统,除了Windows系统外,流行的Ubuntu,Centos,Redhat这些系统应该都没啥问题。
国产的麒麟系统,之前有同事在中标麒麟上跑成功过,不过是默认的HelloWord应用。
后面我在优麒麟上也是运行成功过,但是复杂一点的应用,能正常编译,但是运行的时候会报错:Default font family name can't be null or empty.
在现在用的Ubuntu 20.04操作系统上,其实也遇到这个font family的问题,通过网上提供的方法,是可以解决和正常运行的。
不过尽量先不要用iconfont,用了以后在Windows系统下可能会没有问题,但是在报字体错误的系统下,可能要修改一下那个自定义的字体控制的类。
因为我现在还不知道怎么改,所以采用了最省事的方法,放弃使用iconfont。
Avalonia的应用可以打包成deb安装包。也可以基于软件包设置桌面图标,操作方法参考:
Ubuntu系统下为Avalonia应用创建桌面图标 - wzwyc - 博客园
https://www.cnblogs.com/wzwyc/p/14820893.html
常见问题解决
1、Ubuntu系统下TextBox中文显示乱码
貌似Avalonia必须指定一下当前窗体的字体,不然中文就是会显示乱码,之前是直接设置成“Microsoft YaHei”,会导致Ubuntu系统下找不到相应的字体:
private static string GetPlatformFontFamily() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return "Microsoft YaHei"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return "Menlo"; //换成OSX下的中文字体 } else { return "Noto Sans CJK SC"; } }
2、ToolTip的显示
在要显示ToolTip的控件上加上附加属性:
ToolTip.Tip="Tip内容"
3、Ubuntu设置.net core程序开机自启动
在/etc/systemd/system/ 目录下创建.service文件。
UploadServer.service文件:
[Unit] Description=UploadServer After=network.target [Service] WorkingDirectory=/www/wwwroot/db.cnsos.net/UploadServer/UploadServer/bin/Debug/netcoreapp3.1 ExecStart=/usr/bin/dotnet /www/wwwroot/db.cnsos.net/UploadServer/UploadServer/bin/Debug/netcoreapp3.1/UploadServer.dll Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 SyslogIdentifier=UploadServer [Install] WantedBy=multi-user.target
3、UploadServer.service无法正常启动
发现程序在Ubuntu的终端下用dotnet run可以正常启动和运行,但是设置为service以后,就是无法正常使用。
通过下面的命令看了一下:
sudo journalctl -f -u FileServer.service
发现服务在不停地启动和停止。
看了一下代码,Main函数的未尾使用了Console.ReadLine();
换成:
while (true) { Thread.Sleep(1000); }
应该是service会自动跳过Console.ReadLine(),然后程序就结束了,然后服务本身设置了自动重启,所以不停地停止和重启。
3、Ubuntu系统下路径不正常的问题
程序在Windows系统下测试良好,但是在Ubuntu系统上却无法正常运行,看了一下,是文件路径的问题。
因为客户端在Windows下运行的,客户端上传的路径里的“”需要换成“/”。写了一个路径转换函数:
public static string ChangePath(string path) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { path = path.Replace("\", "/"); if (path.StartsWith("/")) path = path.Substring(1); return path; } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { path = path.Replace("/", "\"); if (path.StartsWith("\")) path = path.Substring(1); return path; } return path; }
另外,在使用Path.Combine(path1,path2)进行路径组合的时候,path2不能以""或“/”开头,不然的话,路径会组合失败。
3、“Default font family name can't be null or empty.”错误问题
部分Linux操作系统下,能够正常编译,但是无法启动应用,会报“Default font family name can't be null or empty.”的错误。应该是跟字体有关系。网上找了一下资料。可以参照以下网址的方法来尝试解决。
https://www.cnblogs.com/joyandjoys/p/14346935.html
4、第三方的MessageBox.Avalonia控件有点问题,会导致应用崩溃退出。
初步判断是因为窗口的图标引起的,而且这个图标不设置也不行。
最新版本已经没有问题。
var msBoxStandardWindow = MessageBox.Avalonia.MessageBoxManager.GetMessageBoxStandardWindow(new MessageBoxStandardParams { ButtonDefinitions = ButtonEnum.Ok, ContentTitle = "提示", ContentMessage = "请输入网址", Icon = Icon.Info, Style = Style.UbuntuLinux, WindowStartupLocation = WindowStartupLocation.CenterOwner, FontFamily = "Microsoft YaHei", }); await msBoxStandardWindow.Show(App.GetActiveWindow());
5、Ubuntu系统下,从IDE上Debug可以正常运行,但是通过系统的桌面图标无法打开。
试了一下,用.desktop里的路径直接在终端里面运行,也是无法正常运行的。在终端上面输出了一些错误信息。看了一下,配置文件的路径,用的是相对路径。
把它改成下面的形式,应用就能正常打开了。
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Formats/AppConfig")