查看原文
其他

.NET跨平台框架Avalonia UI

DotNet 2021-09-24

(给DotNet加星标,提升.Net技能

转自:TwilightLemon
cnblogs.com/TwilightLemon/p/13474796.html

前言


Avalonia 是一个跨平台的.NET UI框架,支持 Windows、Linux、Mac OSX... (以及Android  IOS soon..)


本篇主要介绍Avalonia开发过程和Linux适配环节的几个疑难点..


avalonia for vs安装和.deb安装包部署可参考:

https://www.cnblogs.com/Fengyinyong/p/13346642.html


与WPF类似,Avalonia使用XAML来设计UI...但也有几处比较坑的地方,以下做一些梳理:


一、基本的使用方法


axaml中定义 后台找到并设置对象


在WPF中,当你在xaml文件中定义完UI并设置x:Name就可以在后台中直接使用对象名称进行操作.那是因为vs在你设计时自动生成了.g.i.cs文件(你可以在/obj中看到)


而ava中不同,你需要在后台中自己Get到这个UI对象(与Android类似): 例如:


axaml中定义一个名称为 TB_Title的TextBlock文本标签:


<TextBlock x:Name="TB_Title" HorizontalAlignment="Center" Foreground="White" FontSize="14" VerticalAlignment="Center" Margin="10,0,0,10" Text="My Avalonia Desktop App"/>


在cs中定义并更改标签内容:


TextBlock TB_Title = this.Get<TextBlock>("TB_Title");
TB_Title.Text = "嘻嘻";


这里就用到了this.Get<T>(string Name)方法


T:表示对象类型  Name:为x:Name中定义的名称


注意:在后台查找UI对象 若不是局部变量 应需考虑 时序问题 否则在使用时对象可能是null


建议将所有的控件优先查找出来(如果你控制得比较好可以不用..)


事件


详细的介绍可以看官方文档:http://avaloniaui.net/docs/input/events


有几点比较坑的地方:


1、直接在axaml中定义事件有时候不会成功,可以在后台中定义,例如:


<Button x:Name="btn" Click="Btn_Click">Click Me</Button>
void Btn_Click(object sender, RoutedEventArgs args)
{
//...
}


若不成功可以:


this.Get<Button>("btn").Click+=Btn_Click;
---------------------------------------


2、WPF中的MouseDown/Up事件和Preview事件哪去了?


ava中替换成了 Tapped(轻敲?) 事件


以及 PointerPressed (指针按下 相当于WPF 中的MouseDown) 和 PointerReleased (指针释放  相当于WPF中MouseUp)


为控件注册一个Preview事件:


你的控件名.AddHandler(PointerReleasedEvent,事件名称, RoutingStrategies.Tunnel);


----------------------------------------


3、居然没有MessageBox....(可以到nuget中下载第三方的包)


二、神奇的UI布局


在avalonia中StackPanel是有问题的,它并不会为每一个控件设置宽度或高度  而是优先控件 (WPF中不是这样):

举个例子:


例如在StackPanel中放置若干个TextBlock,你会看到TextBlock延伸到了StackPanel外部 而并没有按照stackpanel的宽度来...


ava中的模式是这样:


如果控件原宽度没有超出则设为stackpanel的宽度


如果超出了...就随它去吧......(??)


此时你就需要手动设置宽度(两种方法):


1、设置绑定:  Width="{Binding Width , ElementName=MyStackPanel(是控件x:Name)}"


2、在后台遍历设置宽度:


ava中并没有给SizeChanged的事件 而是将所有依赖属性改变的事件放到了一个:


PropertyChanged += MainWindow_PropertyChanged;
private void MainWindow_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e){
if (e.Property == WidthProperty){
foreach (Control a in e.Children) {
a.Width = Width;
}
}
}


(十分嫌弃  ..)


神奇的属性Bounds:


如果你仔细一看,会发现各种你找不到的原WPF属性都在这里面:


例如元素的真实高宽:Bounds.Height/Width


元素相对于父控件的位置:Bounds.Position.X/Y


设置ListBox.Items的两种方式:


如果你熟悉了WPF,那么肯定会疑问 ListBox.Items.Add哪去了??


1、数据绑定


文档中展示了比较友好的绑定方式:http://avaloniaui.net/docs/controls/listbox


可以在axaml中设置绑定,将数据放到全局变量中,或者直接对items进行赋值


但是只能有单一的类型...  


2、使用UserControls 并将它们放在List合集中   对items直接赋值..


----------------------------分割线------------------------------


目前发现的坑就有这么多.....但是axaml中的style和animation不是很友好..(animation可以说是辣鸡)


个人看来avalonia还尚未成熟    但足以使用到普通需求中...


下一篇将讲avalonia跑到linux上的一些坑


- EOF -


推荐阅读  点击标题可跳转
新版C#高效率编程指南RabbitMQ与Kafka选型对比SignalR+Vue+Log4net实时日志推送


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

好文章,我在看❤️

: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存