官网:

https://avaloniaui.net/

源码:

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")