张洪瑛 發表於 2020-10-22 10:08:00

国产化即时通信系统开发 -- 使用Avalonia实现GGTalk的UI界面(Linux、Ubuntu、UOS、中标麒麟)

<p class="p">距离2013年开源GGTalk以来,7年已经过去了,GGTalk现在有了完整的PC版、安卓版、iOS版(即将发布),以及Xamarin版本。</p>
<p class="p">然而,时代一直在变化,在今天,有个趋势越来越明显,那就是政府系统将逐渐迁移到Linux以及国产化的操作系统和数据库上面来。</p>
<p class="p">所以,GGTalk也将随顺这一必然的趋势,服务端将推出Linux(CentOS)版本,客户端也将支持Linux/Ubuntu、中标麒麟、UOS等国产操作系统。</p>
<p class="p">基于.NET Core,服务端的迁移相对容易;而客户端的迁移则繁琐很多,其主要在于界面UI部分需要完全重写。</p>
<p class="p">在考察了众多的Linux上的UI技术之后,我们选定了现在很主流的Avalonia框架作为GGTalk的客户端版本的UI技术。&nbsp;</p>
<p class="p">在使用Avalonia开发GGTalk客户端linux版本的过程中,我们遇到了很多坑,也积累了很多经验,接下来我们将通过“Avalonia跨平台UI开发”这个系列,将这些过坑的经验分享出来,为后来者提供参考。</p>
<p class="p">那下面先从Avalonia简介开始吧。</p>
<h1 class="p">一. Avalonia简介<span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 14pt"><br></span></h1>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">Avalonia是一个基于WPF XAML的跨平台UI框架,并支持多种操作系统:Windows(.NET Framework,.NET Core),Linux(GTK),MacOS,Android和iOS。</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">通过Avalonia,可以使用XAML标记来实现应用程序的外观,同时使用代码来实现其行为。</span></p>
<p><span style="font-size: 15px">Avalonia官网:https://avaloniaui.net/</span></p>
<p><span style="font-size: 15px">Avalonia开源地址:https://github.com/AvaloniaUI/Avalonia</span></p>
<p class="p">&nbsp;</p>
<h2><span style="font-family: &quot;Microsoft YaHei&quot;"><strong>1.开发准备</strong></span></h2>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">VS 2019安装扩展&nbsp;https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio</span></p>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">安装之后就有了Avalonia开发模板。</span></p>
<p class="p"><img src="https://img2020.cnblogs.com/blog/20404/202009/20404-20200905165107803-1547972015.png" alt="" loading="lazy">&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">选择 Avalonia&nbsp;MVVM&nbsp;Application ,就可以创建一个项目。</span></p>
<p>&nbsp;</p>
<h3><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 18px"><strong>2. GGTalk 登录界面示例</strong></span></h3>
<p class="p"><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">新建一个基础项目GGTalk,在MainWindow.xaml 添加图片、按钮、输入框等控件,就是WPF XAML 的语法,直接可以实现对应布局。</span></p>
<div class="cnblogs_code">
<pre>&lt;Window xmlns=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://github.com/avaloniaui</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      xmlns:x</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://schemas.microsoft.com/winfx/2006/xaml</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      xmlns:vm</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">clr-namespace:myoneavalonia.ViewModels;assembly=myoneavalonia</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      xmlns:d</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://schemas.microsoft.com/expression/blend/2008</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      xmlns:mc</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://schemas.openxmlformats.org/markup-compatibility/2006</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      mc:Ignorable</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">d</span><span style="color: rgba(128, 0, 0, 1)">"</span> d:DesignWidth=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">430</span><span style="color: rgba(128, 0, 0, 1)">"</span> d:DesignHeight=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">330</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      x:Class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">myoneavalonia.Views.MainWindow</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      Icon</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/Assets/avalonia-logo.ico</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      Title</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">GGTalk</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      Width</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">430</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      Height</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">340</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      CanResize</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">False</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      WindowStartupLocation</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">CenterScreen</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
   

    &lt;Design.DataContext&gt;
      &lt;vm:MainWindowViewModel/&gt;
    &lt;/Design.DataContext&gt;


  &lt;Window.Styles &gt;
            &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TextBox.tb1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
                &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0,-40,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
                &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Height</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">26</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
                &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Width</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">250</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
                &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Watermark</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">账号</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
                &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BorderBrush</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#80c0ff</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
            &lt;/Style&gt;
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TextBox.tb2</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0,35,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Height</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">26</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Width</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">250</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Watermark</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">密码</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BorderBrush</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#80c0ff</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">PasswordChar</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">*</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;!--######&lt;TextBox标签&gt;######--&gt;
         
         
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Image.img1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0,-250,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Width</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">430</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Image.img2</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0,-190,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Width</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">73</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Height</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">73</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;!--######&lt;Image标签&gt;######--&gt;
         
         
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TextBlock.tbk1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">5,5,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Foreground</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">White</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TextBlock.tbk2</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">292,213,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Foreground</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#0c7ab9</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Cursor</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hand</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">TextBlock.tbk3</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">275,305,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Foreground</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#696969</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;!--######&lt;TextBlock标签&gt;######--&gt;

         

         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Button.bt1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0,195,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Width</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">250</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Height</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">40</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Background</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#407cff</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Foreground</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">White</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">FontSize</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">17</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;!--######&lt;Button标签&gt;######--&gt;

      
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">CheckBox.cbx1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">89,105,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BorderBrush</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#3c9fc5</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;Style Selector=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">CheckBox.cbx2</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Margin</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">190,105,0,0</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
               &lt;Setter Property=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BorderBrush</span><span style="color: rgba(128, 0, 0, 1)">"</span> Value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#3c9fc5</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
         &lt;/Style&gt;
         &lt;!--######&lt;CheckBox标签&gt;######--&gt;   
       &lt;/Window.Styles&gt;
   
   
   
&lt;StackPanel&gt;   
    &lt;Border Background=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">White</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            BorderBrush</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Gray</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            BorderThickness</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            Padding</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            Width</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">430</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
            Height</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">340</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;            
      &lt;Grid&gt;               
            &lt;Image Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img1</span><span style="color: rgba(128, 0, 0, 1)">"</span> Source=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">D:\yzy\avaloniafiles\myoneavalonia\Resources\image_sign.png</span><span style="color: rgba(128, 0, 0, 1)">"</span> &gt;&lt;/Image&gt;
            &lt;Image Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img2</span><span style="color: rgba(128, 0, 0, 1)">"</span> Source=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">D:\yzy\avaloniafiles\myoneavalonia\Resources\8.png</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
            &lt;TextBlock Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tbk1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;GGTalk <span style="color: rgba(128, 0, 128, 1)">2020</span>&lt;/TextBlock&gt;
            &lt;TextBlock Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tbk2</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;注册登录&lt;/TextBlock&gt;
            &lt;TextBlock Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tbk3</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;GGTalk 企业即时通讯系统&lt;/TextBlock&gt;
            &lt;TextBox Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tb1</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
            &lt;TextBox Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">tb2</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
            &lt;CheckBox Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">cbx2</span><span style="color: rgba(128, 0, 0, 1)">"</span> &gt;自动登录&lt;/CheckBox&gt;
            &lt;CheckBox Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">cbx1</span><span style="color: rgba(128, 0, 0, 1)">"</span> &gt;记住密码&lt;/CheckBox&gt;
            &lt;Button Classes=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">bt1</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;登录&lt;/Button&gt;
      &lt;/Grid&gt;            
    &lt;/Border&gt;
&lt;/StackPanel&gt;   

&lt;/Window&gt;</pre>
</div>
<p>&nbsp;如果熟悉WPF XAML,那么上面的代码理解起来就非常容易了。</p>
<h1><span style="font-family: &quot;Microsoft YaHei&quot;">二. 运行程序</span></h1>
<p>&nbsp;我们在Ubuntu和中标麒麟上运行这个程序,效果如下所示(还不错吧):</p>
<p class="p"><img src="https://img2020.cnblogs.com/blog/20404/202009/20404-20200914152600963-1769046527.jpg" alt="" loading="lazy"></p>
<p class="p">(在Ubuntu上运行的效果)</p>
<p class="p"><img src="https://img2020.cnblogs.com/blog/20404/202009/20404-20200914152616194-1767303813.jpg" alt="" loading="lazy"></p>
<p class="p">(在中标麒麟上运行的效果)</p>
<h1><span style="font-family: &quot;Microsoft YaHei&quot;">三. 在使用Avalonia时遇到的坑</span></h1>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">在开发这个登录界面的时候,遇到了三个坑。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">(1)当将&lt;Textbox&gt;输入框标签的height属性设置为小于或等于25时,在输入框的右边,</span><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">会多出一个下拉框。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">研究了半天才发现跟输入框高度有关,瞬间泪崩......</span></p>
<p><span style="font-family: 微软雅黑"><img src="https://img2020.cnblogs.com/blog/20404/202009/20404-20200905165911864-1797758289.png" alt="" loading="lazy"><span style="font-family: &quot;PingFang SC&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif">&nbsp;</span></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">(2)官方文档中有一些控件无法正常使用,提示无法解析该类型,在运行时会报错,比如:</span></p>
<p><span style="font-family: 微软雅黑"><img src="https://img2020.cnblogs.com/blog/20404/202009/20404-20200905170050866-2145282314.png" alt="" loading="lazy"></span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">解决方案:在官网(https://avaloniaui.net/)上下载对应的控件,然后引入项目中就不会报错了。</span></p>
<p>&nbsp;<span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">(3)另外,在Ubuntu上运行Avalonia项目后如果没有显示界面,这时就需要去修改/etc/apt/sources.list文件,更新软件源后就能够显示界面了。</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">更换软件源的步骤:</span></p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">Ubuntu 的源存放在在 /etc/apt/ 目录下的 sources.list 文件中,修改前我们先备份,在终端中执行以下命令:</span></p>
<div class="cnblogs_code">
<pre>sudo cp /etc/apt/sources.list /etc/apt/sources.list.bcakup</pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">然后执行下面的命令打开 sources.list 文件,清空里面的内容</span></p>
<div class="cnblogs_code">
<pre>sudo gedit /etc/apt/sources.list</pre>
</div>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">把下面阿里云与清华大学的 Ubuntu 源复制进去,保存后退出</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"># 阿里云源
deb http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)">##測試版源
deb http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)"># 源碼
deb</span>-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)">##測試版源
deb</span>-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)">

# 清华大学源
deb http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse</span>
deb http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)">##測試版源
deb http:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)"># 源碼
deb</span>-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse</span>
deb-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse</span>
<span style="color: rgba(0, 0, 0, 1)">##測試版源
deb</span>-src http:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse</span></pre>
</div>
<p>接着在终端上执行以下命令更新软件列表,检测出可以更新的软件:</p>
<div class="cnblogs_code">
<pre>sudo apt-<span style="color: rgba(0, 0, 255, 1)">get</span> <span style="color: rgba(255, 0, 0, 1)">update</span></pre>
</div>
<p>最后在终端上执行以下命令进行软件更新:</p>
<div class="cnblogs_code">
<pre>sudo apt-<span style="color: rgba(0, 0, 255, 1)">get</span> <span style="color: rgba(255, 0, 0, 1)">upgrade</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-family: &quot;Microsoft YaHei&quot;; font-size: 15px">到这里,GGTalk的登录界面就实现完成了。同样的,我们会将GGTalk的Linux/国产化操作系统的版本的源码全部放出来给大家参考,敬请期待。</span></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/justnow/p/13608404.html
頁: [1]
查看完整版本: 国产化即时通信系统开发 -- 使用Avalonia实现GGTalk的UI界面(Linux、Ubuntu、UOS、中标麒麟)