.Net-Avalonia学习笔记(三)-从WPF转移到Avalonia的注意事项
1、XAML
(1)Style样式
Avalonnia中的样式Style
为css
,样式不像在WPF中存储在Resources
集合中,而是存储在一个独立的Styles
集合中。控件模板ControlThere除外。示例代码如下:
<UserControl>
<UserControl.Styles>
<!-- 让带有 h1 样式类的 TextBlock 具有 24 点的字体大小 -->
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="24"/>
</Style>
</UserControl.Styles>
<TextBlock Classes="h1">Header</TextBlock>
<UserControl>
(2)Data Templates数据模版
在Avalonia UI中,数据模板不会存储在应用程序资源中。相反,数据模板要么放置在控件的DataTemplates
集合内,要么放置在Application
上。示例如下:
<UserControl xmlns:viewmodels="using:MyApp.ViewModels"
x:DataType="viewmodels:ControlViewModel">
<UserControl.DataTemplates>
<DataTemplate DataType="viewmodels:FooViewModel">
<Border Background="Red" CornerRadius="8">
<TextBox Text="{Binding Name}"/>
</Border>
</DataTemplate>
</UserControl.DataTemplates>
<!-- 假设ControlViewModel.Foo是MyApp.ViewModels.FooViewModel类型的对象,
则此处将显示一个具有圆角半径为8的红色边框,其中包含一个TextBox。
只有在使用编译绑定时才需要DataType,因此可以对其类型检查。 -->
<ContentControl Content="{Binding Foo}"/>
<UserControl>
(3)Data Template Selector数据模板选择器
在WPF中,您可以创建DataTemplateSelector
来根据提供的数据选择或创建DataTemplate
。在Avalonia中,您不能这样做,但是您可以实现IDataTemplate
,它可以被看作是DataTemplateSelector
的替代品。示例地址:https://docs.avaloniaui.net/zh-Hans/docs/get-started/wpf/datatemplates
(4)WPF的HierarchicalDataTemplate
在WPF中的HierarchicalDataTemplate
在Avalonia中被称为TreeDataTemplate
(因为前者难以输入!)
(5)控件基类TemplatedControl
与Control
WPF中的UIElement
和FrameworkElement
是非模板控件的基类,大致对应于Avalonia中的Control
类。而WPF中的Control
类则是一个模板控件,Avalonia中相应的类是TemplatedControl
。
- 在WPF/UWP中,您将从
Control
类继承来创建新的模板控件,而在Avalonia中,您应该从TemplatedControl
继承。 - 在WPF/UWP中,您将从
FrameworkElement
类继承来创建新的自定义绘制控件,而在Avalonia中,您应该从Control
继承。
因此,简要总结如下:
UIElement
🠞Control
FrameworkElement
🠞Control
Control
🠞TemplatedControl
(6)WPF的DependencyProperty
Avalonia中与DependencyProperty
相对应的是StyledProperty
,然而Avalonia的属性系统比WPF更丰富,还包括DirectProperty
用于将标准CLR属性转换为Avalonia属性。StyledProperty
和DirectProperty
的共同基类是AvaloniaProperty
。
(7)更简易的Grid
在Avalonia中,可以使用字符串来指定列和行定义,避免了WPF中笨重的语法:<Grid ColumnDefinitions="Auto,*,32" RowDefinitions="*,Auto">
。在WPF中,Grid
的一个常见用法是将两个控件堆叠在一起。在Avalonia中,为此,您可以直接使用Panel
,它比Grid
更轻量级。
(8)Tunnelling Events
Avalonia确实有事件隧道传播,但它们不是通过单独的Preview CLR事件处理程序公开的。要订阅一个事件隧道传播事件,您需要使用AddHandler方法,并传递RoutingStrategies.Tunnel参数:
target.AddHandler(InputElement.KeyDownEvent, OnPreviewKeyDown, RoutingStrategies.Tunnel);
void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
// 处理程序代码
}
(9)EventManager.RegisterClassHandler变化
// WPF
static MyControl()
{
EventManager.RegisterClassHandler(typeof(MyControl), MyEvent, HandleMyEvent));
}
private static void HandleMyEvent(object sender, RoutedEventArgs e)
{
}
// Avalonia
static MyControl()
{
MyEvent.AddClassHandler<MyControl>((x, e) => x.HandleMyEvent(e));
}
private void HandleMyEvent(RoutedEventArgs e)
{
}
请注意,在WPF中,您必须将类处理程序添加为静态方法,而在Avalonia中,类处理程序不是静态的:通知会自动定向到正确的实例。在这种情况下,事件处理程序通常的sender参数是不必要的,一切保持强类型。
(10)PropertyChangedCallback
在WPF中,监听DependencyProperties的变化可能会变得复杂。当您注册一个DependencyProperty
时,可以提供一个静态的PropertyChangedCallback
,但如果您想从其他地方监听属性变化,事情可能会变得复杂和容易出错。
在Avalonia中,注册时没有PropertyChangedCallback
,而是在控件的静态构造函数中添加了一个类监听器,方式与添加事件类监听器的方式非常相似。
(11)RenderTransforms 和 RenderTransformOrigin
在WPF和Avalonia中,RenderTransformOrigin是不同的:如果应用了RenderTransform
,请注意Avalonia中RenderTransformOrigin的默认值是RelativePoint.Center
,而在WPF中默认值是RelativePoint.TopLeft
(0, 0)。在像Viewbox这样的控件中,相同的代码将导致不同的渲染行为:
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/p/18320573