基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架

这篇具有很好参考价值的文章主要介绍了基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架

Avalonia简介:

Avalonia是.NET的一个跨平台UI框架,提供了一个灵活的样式系统,支持广泛的操作系统,如Windows、Linux、macOS,并对Android、iOS和WebAssembly提供了实验性支持。

为什么使用Avalonia:

之前已经了解了基于Avalonia的项目在国产麒麟系统中运行的案例。正是Avalonia在跨平台的出色表现,学习和了解Avalonia这个UI框架显得十分有必要。本项目采用的是最新稳定版本11.0.0-rc1.1。希望通过该项目了解和学习Avalonia开发的朋友可以在我的github上拉取代码,同时希望大家多多点点star。

https://github.com/raokun/TerraMours.Chat.Ava

项目需求:

Web端的AI应用我已经开发了一个AI聊天平台了。希望开发一个跨平台的AI聊天和其他功能的客户端平台。有个面试邀请是要求avalonia应用经验要求。写这样一个项目来学习和了解Avalonia。同时麒麟系统的开放版本也发布了也想后面部署一个将这个项目部署在openKylin 1.0 的系统上。

开发环境:

.net 7

篇幅有限,创建项目的部分跳过,需要了解的可以看我之前的基础博客:https://www.raokun.top/archives/chuang-jian-avalonia-mo-ban-xiang-mu---ji-chu

下面我会直接以TerraMours.Chat.Ava项目为例子 来介绍项目开发过程和各技术的应用

1.nuget包引用

引用包介绍:

  • Avalonia 版本11.0.0-rc1.1,稳定版本,其他基于avalonia的包要选用支持11.0.0-rc1.1的版本

  • Avalonia.ReactiveUI MVVM 架构模式的工具库,创建avalonia项目时会提示选择。

  • DialogHost.Avalonia 它提供了一种简单的方式来显示带有信息的对话框或在需要信息时提示用户。

  • FluentAvaloniaUI UI库,并将更多WinUI控件引入Avalonia

  • System.Data.SQLite 本地数据库SQLite

  • CsvHelper Csv导入导出工具库

  • Markdown.Avalonia 用于显示markdown文本的工具,用于展示聊天结果的渲染

  • Betalgo.OpenAI 调用ChatGpt的扩展库

<PackageReference Include="Avalonia" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.0-rc1.1" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-rc1.1" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.0.0-rc1.1" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.0.0-rc1.1" />
<PackageReference Include="DialogHost.Avalonia" Version="0.7.4" />
<PackageReference Include="FluentAvaloniaUI" Version="2.0.0-rc1" />
<PackageReference Include="System.Data.SQLite" Version="1.0.117" />
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="Markdown.Avalonia" Version="11.0.0-d1" />
<PackageReference Include="Markdown.Avalonia.SyntaxHigh" Version="11.0.0-d1" />
<PackageReference Include="Markdown.Avalonia.Tight" Version="11.0.0-d1" />
<PackageReference Include="Betalgo.OpenAI" Version="7.1.2-beta" />

2.功能介绍

项目开发的功能分为如下:

1.通用框架:

  • VMLocator: ViewModel 定位器。方便地获取和管理 ViewModel 实例,从而实现界面和数据的解耦和模块化,提高代码的可维护性和可测试性。
  • 国际化: 使用 CultureInfo.CurrentCulture 来实现多语言支持和本地化
  • 本地化数据:通过SQLite实现数据本地化
  • CSV导入导出:实现数据的迁移和补充
  • 自定义快捷键: 自定义快捷键,方便操作。发挥客户端的按键优势。
  • 自定义字体
  • 全局样式

2.界面交互

  • LoadView.axaml 加载界面:系统打开时候的加载界面,用于首页替换的技术实践。可改造成登陆界面。
  • MainWindow.axaml 首页
  • MainView.axaml 主界面
  • DataGridView.axaml 会话列表
  • ChatView.axaml 聊天界面
  • ApiSettingsView.axaml API配置

3.功能开发

1.通用功能开发

1.VMLocator ViewModel 定位器

VMLocator 类在 Avalonia 项目中的作用是作为一个静态的 ViewModel 定位器,用于管理和提供各个 ViewModel 类的实例。ViewModel 是 MVVM 模式中用于处理界面逻辑和数据的类,而 ViewModel 定位器则负责管理 ViewModel 的实例,供界面进行数据绑定和交互。

优点:
  1. 提供了一种集中管理 ViewModel 的机制,使得整个应用程序可以方便地访问和使用各个 ViewModel 实例。
  2. 通过使用静态属性和延迟初始化的方式,避免了频繁创建 ViewModel 实例的开销,提高了程序的性能和效率。
  3. 可以在需要的时候动态获取 ViewModel 实例,而不需要手动实例化 ViewModel 类。
  4. 可以在不同的界面和组件之间共享同一个 ViewModel 实例,实现数据的共享和一致性
1.创建资源类VMLocator
2.注入资源

app.axaml.cs中OnFrameworkInitializationCompleted方法加入

var VMLocator = new VMLocator();
Resources.Add("VMLocator", VMLocator);

2.国际化

1.添加不同语言的资源文件
1.创建个语言的资源文件
2.文件内容

代码如下:

<ResourceDictionary xmlns="https://github.com/avaloniaui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
					xmlns:system="clr-namespace:System;assembly=System.Runtime">
    <!-- Add Resources Here -->
	<system:String x:Key="My.Strings.ConversationHitoryInfo">
		"conversation history limit" is a client option, not an API parameter.
		When the set value (tokens) is exceeded,
		the conversation history will be automatically summarized.
	</system:String>
</ResourceDictionary>

资源文件中定义了各个配置的说明文本的内容,通过使用 CultureInfo.CurrentCulture 来实现多语言支持和本地化

2.添加Application.Resources

App.axaml中添加资源文件配置

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceInclude Source="/Assets/lang/zh-CN.axaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
3.添加AvaloniaXaml

在csproj中添加AvaloniaXaml

<AvaloniaXaml Update="Assets\lang\zh-CN.axaml">
    <SubType>Designer</SubType>
</AvaloniaXaml>
什么是AvaloniaXaml:

AvaloniaXaml 是 Avalonia 框架中用于定义用户界面的 XAML 格式。它具有以下作用和特点:

作用:

  1. 声明式定义用户界面:AvaloniaXaml 允许开发人员使用 XAML 标记语言来声明用户界面的结构和外观。它提供了一种简洁、可读性强的方式来描述应用程序的用户界面。
  2. 分离视图与逻辑:通过使用 AvaloniaXaml,开发人员可以将用户界面的定义与应用程序的逻辑代码进行分离。这种分离可以提高代码的组织性、可维护性和可测试性。
  3. 支持样式和模板:AvaloniaXaml 提供了强大的样式和模板机制,使开发人员能够轻松地定制和重用用户界面的外观和行为。这样,可以实现更灵活和可扩展的界面设计。
4.自动判断语言

通过CultureInfo.CurrentCulture 实现系统随机器的语言系统自动切换显示语言实现国际化配置。

CultureInfo.CurrentCulture 是一个表示当前线程所使用的区域设置(Culture)的属性。它提供了关于当前文化信息(如语言、国家/地区、日期和时间格式等)的访问和管理。

在MainWindow的构造函数中添加

代码如下:

 var cultureInfo = CultureInfo.CurrentCulture;
if (cultureInfo.Name == "zh-CN") {
    Translate("zh-CN");
}
Translate 方法

代码如下:

#region 国际化
    public void Translate(string targetLanguage) {
    var translations = App.Current.Resources.MergedDictionaries.OfType<ResourceInclude>().FirstOrDefault(x => x.Source?.OriginalString?.Contains("/Lang/") ?? false);

    if (translations != null)
        App.Current.Resources.MergedDictionaries.Remove(translations);

    App.Current.Resources.MergedDictionaries.Add(
        (ResourceDictionary)AvaloniaXamlLoader.Load(
            new Uri($"avares://TerraMours.Chat.Ava/Assets/lang/{targetLanguage}.axaml")
        )
    );
}
#endregion

3.本地化数据

本地化数据采用了SQLite本地数据库,直接使用SQLite,用sql查询,简单高效,但是需要开发人员对sql的了解程度高。当然,也可以其他ORM框架调用SQLite。

1.SQLite特点

SQLite 是一种嵌入式关系型数据库管理系统(RDBMS),有以下优点,这些优点也是为什么客户端广泛使用它的原因:

  1. 简单易用:SQLite 的设计目标之一是简化数据库系统的使用和管理。它有一个简洁的操作接口,易于学习和使用,无需繁琐的配置和管理步骤。因此,开发人员可以很快上手并快速开发出功能丰富的应用程序。
  2. 无服务器架构:与大多数数据库管理系统不同的是,SQLite 是一个无服务器的数据库引擎,数据库以一个文件的形式存储在磁盘上。这种架构使得 SQLite 的部署和维护变得非常简单,不需要安装和配置额外的服务器。
  3. 轻量级和高性能:由于 SQLite 的设计目标是资源消耗低、性能高效,它被认为是一个轻量级的数据库引擎。SQLite 数据库文件通常较小,并且可以在资源受限的环境中快速运行。同时,SQLite 使用了精简的 SQL 语法和优化技术,提供了快速的查询和高效的数据读写性能。
  4. 跨平台支持:SQLite 是一个跨平台数据库引擎,可以在多种操作系统上运行,包括 Windows、Linux、macOS 和嵌入式系统等。这种跨平台的特性使得开发人员可以方便地在不同的环境中使用 SQLite,并轻松共享和迁移数据库文件。
  5. 高度可移植:SQLite 数据库文件是独立于操作系统和硬件的二进制文件,可以在不同的平台之间自由传输和共享。这种可移植性使得 SQLite 成为一个理想的选择,特别是在需要在不同系统之间进行数据共享或迁移的情况下。
  6. ACID 事务支持:SQLite 支持事务处理和完整性约束,遵循 ACID(原子性、一致性、隔离性和持久性)原则。这意味着开发人员可以使用 SQLite 进行可靠的数据处理,并确保数据的正确性和一致性。
2.创建数据库操作类 DatabaseProcess
1.数据库连接
using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
2.创建表和索引

代码如下:

public void CreateDatabase() {
            using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
            string sql = "CREATE TABLE phrase (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL DEFAULT '', phrase TEXT NOT NULL DEFAULT '');";

            using var command = new SQLiteCommand(sql, connection);
            // phrase创建表格
            connection.Open();
            command.ExecuteNonQuery();

            // phrase索引
            sql = "CREATE INDEX idx_text ON phrase (phrase);";
            command.CommandText = sql;
            command.ExecuteNonQuery();
}
3.查询列表(例)

代码如下:

public async Task<List<string>> GetPhrasesAsync() {
    List<string> phrases = new List<string>();
    string sql = "SELECT name FROM phrase ORDER BY name COLLATE NOCASE";

    using (var command = new SQLiteCommand(sql, memoryConnection)) {
        using var reader = await command.ExecuteReaderAsync();
        while (await reader.ReadAsync()) {
            phrases.Add(reader.GetString(0));
        }
    }
    return phrases;
}
4.新增(例)
public async Task SavePhrasesAsync(string name, string phrasesText) {
    using var connection = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
    await connection.OpenAsync();

    using var transaction = connection.BeginTransaction();
    try {
        string sql = $"INSERT INTO phrase (name, phrase) VALUES (@name, @phrase)";

        using var command = new SQLiteCommand(sql, connection);
        command.Parameters.AddWithValue("@name", name);
        command.Parameters.AddWithValue("@phrase", phrasesText);

        await command.ExecuteNonQueryAsync();

        transaction.Commit();
    }
    catch (Exception) {
        transaction.Rollback();
        throw;
    }
    await memoryConnection.CloseAsync();
    await DbLoadToMemoryAsync();
}

4.CSV导入导出

通过CsvHelper实现数据的导入导出

1.选择文件

弹出选择文件框,限制文件类型为CSV

代码如下:

private async Task ImportChatLogAsync() {
    var dialog = new FilePickerOpenOptions {
        AllowMultiple = false,
        Title = "Select CSV file",
        FileTypeFilter = new List<FilePickerFileType>
        {new("CSV files (*.csv)") { Patterns = new[] { "*.csv" } },
         new("All files (*.*)") { Patterns = new[] { "*" } }}
    };

    var result = await (Application.Current!.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)!.MainWindow!.StorageProvider.OpenFilePickerAsync(dialog);

    if (result.Count > 0) {
        var selectedFilePath = result[0].Path.LocalPath;
        try {
            var msg = await _dbProcess.ImportCsvToTableAsync(selectedFilePath);
            var cdialog = new ContentDialog() { Title = msg, PrimaryButtonText = "OK" };
            await ContentDialogShowAsync(cdialog);
        }
        catch (Exception ex) {
            var cdialog = new ContentDialog() { Title = "Failed to import log." + Environment.NewLine + "Error: " + ex.Message, PrimaryButtonText = "OK" };
            await ContentDialogShowAsync(cdialog);
        }
        VMLocator.DataGridViewModel.ChatList = await _dbProcess.SearchChatDatabaseAsync();
    }
}
2.导入到数据库

CSV从文件导入数据,跳过标题行,取得数据,将数据插入数据库

代码如下:

 // CSV从文件导入数据
using var reader = new StreamReader(fileName, System.Text.Encoding.UTF8);
var config = new CsvConfiguration(CultureInfo.InvariantCulture) {
    HasHeaderRecord = true,
    Delimiter = ","
};
using var csvReader = new CsvReader(reader, config);
csvReader.Read(); // 跳过标题行

using var con = new SQLiteConnection($"Data Source={AppSettings.Instance.DbPath}");
await con.OpenAsync();
using (var transaction = con.BeginTransaction()) {
    try {
        while (await csvReader.ReadAsync()) // 导入数据行
        {

            // 数据取得
            var rowData = new List<string>();
            for (int i = 1, loopTo = columnEnd; i <= loopTo; i++) // 从第二排到第八排
                rowData.Add(csvReader.GetField(i));
            // 创建插入语句
            string values = string.Join(", ", Enumerable.Range(0, rowData.Count).Select(i => $"@value{i}"));

            string insertQuery = $"INSERT INTO {tableName} ({columnNames}) VALUES ({values});";

            // 将数据插入数据库
            using (var command = new SQLiteCommand(insertQuery, con)) {
                for (int i = 0, loopTo1 = rowData.Count - 1; i <= loopTo1; i++)
                    command.Parameters.AddWithValue($"@value{i}", rowData[i]);
                await command.ExecuteNonQueryAsync();
            }
            processedCount += 1;
        }

        transaction.Commit();
        msg = $"Successfully imported log. ({processedCount} Records)";
    }
    catch (Exception) {
        transaction.Rollback();
        throw;
    }
}
await con.CloseAsync();

5.自定义快捷键

1.CustomNumericUpDown
  1. 提供了一种自定义的 NumericUpDown 控件,可以用于在用户界面中显示和编辑数字值。NumericUpDown 控件通常用于允许用户输入数值或选择数值的场景。
  2. 通过重写 OnApplyTemplate 方法,该类可以在控件的模板应用后,获取到控件内部的 TextBox 控件,并订阅其 KeyDown 事件。
  3. 在 TextBox_KeyDown 事件处理程序中,实现了自定义的键盘输入逻辑,只允许在 TextBox 中输入数字、小数点以及一些控制键。
  4. 在 DetachedFromVisualTree 事件中,清理了事件的订阅,以避免内存泄漏。
  5. 通过实现 IStyleable 接口,可以定义该控件的样式(StyleKey)。

6.自定义字体

1.添加 AvaloniaResource

在csproj中添加

<AvaloniaResource Include="Assets\Lato-Regular.ttf" /> 
<AvaloniaResource Include="Assets\migu-1m-regular.ttf" />
2.设置控件对应的字体
<Style Selector="TextBlock">
    <Setter Property="FontFamily" Value="avares://TmCGPTD/Assets/Lato-Regular.ttf#Lato" />
    <Setter Property="Foreground" Value="rgb(220, 220, 220)" />
</Style>

7.全局样式

1.添加Styles.axaml

Styles.axaml的作用是全局定义样式,控制整个系统的样式风格

2.Application.Styles

app.axaml中添加

代码如下:

<Application.Styles>
    <StyleInclude Source="avares://TerraMours.Chat.Ava/Assets/Styles.axaml" />
</Application.Styles>
3.添加AvaloniaResource

csproj添加AvaloniaResource

  <ItemGroup>
	<AvaloniaResource Include="Assets\Styles.axaml" />
  </ItemGroup>

项目截图:

篇幅有限,功能开发部分请跳转下篇

基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发2-功能开发文章来源地址https://www.toymoban.com/news/detail-573746.html

阅读如遇样式问题,请前往个人博客浏览: https://www.raokun.top
拥抱ChatGPT:https://ai.terramours.site
开源项目地址:https://github.com/raokun/TerraMours.Chat.Ava

到了这里,关于基于Avalonia 11.0.0+ReactiveUI 的跨平台项目开发1-通用框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Avalonia学习实践(二)--跨平台支持及发布

    Avalonia主打跨平台,号称一套代码支持Windows, macOS, Linux, iOS, Android操作系统,其基础是基于.NET Standard 2.0的一系列库,也就是只要平台能支持.NET Standard 2.0,就能运行Avalonia开发的应用。然而理想很丰满、现实很骨感,并不是说跨平台Avalonia没有做到,而是过程中免不了会有些小

    2024年02月07日
    浏览(56)
  • 探索Avalonia:C#跨平台UI框架的力量

    随着跨平台应用的需求不断增长,开发人员需要一种能够在不同操作系统上运行的用户界面(UI)框架。 Avalonia 是一种引人注目的选择。在本文中,我们将深入了解 Avalonia 是什么,它与 WPF 的区别,以及它的 UI 绘制引擎和原理、优点,以及一个简单的示例代码。 Avalonia 是什

    2024年04月08日
    浏览(50)
  • Net跨平台UI框架Avalonia入门-安装和使用

    Avalonia UI是是Net的跨平台UI框架,支持 Windows、Linux、iOS 和 Android,与Net其他UI框架相比,如WPF(Windows平台)、MAUI跨平台控件(Android、iOS、macOS 和 Windows),主要优势是支持Linux。在国产化的需求下,对于C#开发的程序员,Avalonia适合用来开发Linux的桌面客户端。 v11版本已经发布

    2024年02月05日
    浏览(82)
  • .NET / C# 开发 Ubuntu Desktop 跨平台图形界面桌面程序 Avalonia - Visual Studio 安装/创建/运行指南 (一)

    Avalonia 是一个开源的跨平台应用程序框架,用于构建桌面应用程序。它使用 C# 和 XAML 进行开发,可以在 Windows、macOS、iOS、Android 及 Linux 等多个平台上运行。Avalonia 项目地址:https://github.com/AvaloniaUI/Avalonia 本文快速介绍如何入门使用 Avalonia 编写和执行 Ubuntu Desktop 图形界面桌面

    2024年02月01日
    浏览(66)
  • 跨平台应用开发进阶(六十二):如何把 uni-app APP项目转换成小程序

    随着移动互联网的快速发展,移动应用已成为生活中不可或缺的一部分。与此同时,跨平台开发也得到越来越多的关注,因为它可以提高应用程序的效率并降低开发成本。 uni-app 是一种跨平台开发框架,基于 Vue.js ,并且可以在多个平台如微信小程序、支付宝小程序、H5等上运

    2024年02月15日
    浏览(67)
  • 跨平台应用开发进阶(五十)uni-app ios web-view嵌套H5项目白屏问题分析及解决

    应用 uni-app 框架开发好APP上架使用过程中,发现应用经过长时间由后台切换至前台时,通过 webview 方式嵌套的H5页面发生白屏现象。 任何手机设备上,当手机内存不足时,os都会回收资源。一般是先回收后台打开的资源。如果当前应用占用的资源过高,当前应用也有可能崩溃

    2024年02月14日
    浏览(51)
  • 关于 Delphi 11.3跨平台开发Android调用 JNI JAR java 的说明和注意事项

    关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码 的说明 V2017.10.18 (* ************************************************ *) (* *) (* *) (* 设计:爱吃猪头肉 Flying Wang 2015-04-15  *) (* 上面的版权声明请不要移除。 *) (* *) (* ************************************************ *) 本人所

    2024年02月07日
    浏览(59)
  • 一个基于.NET Core开源、跨平台的仓储管理系统

    今天给大家推荐一个基于.NET Core开源、跨平台的仓储管理系统,数据库支持MSSQL/MySQL:ZEQP.WMS。 仓储管理系统(Warehouse Management System,WMS)是一种用于管理和控制仓库操作的软件系统,它可以帮助企业实现对仓库内物品的跟踪、存储、拣选、包装和发运等全过程管理,提高仓

    2024年02月21日
    浏览(150)
  • 基于 FFMPEG 的跨平台视频播放器简明教程(三):视频解码

    基于 FFmpeg 的跨平台视频播放器简明教程(一):FFMPEG + Conan 环境集成 基于 FFmpeg 的跨平台视频播放器简明教程(二):基础知识和解封装(demux) 在前面章节 基于 FFMPEG 的跨平台视频播放器简明教程(二):基础知识和解封装(demux) 中我们引入了视频编解码的基础知识以

    2024年02月08日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包