.Net-Avalonia学习笔记(三)-从WPF转移到Avalonia的注意事项

1、XAML

(1)Style样式

  Avalonnia中的样式Stylecss,样式不像在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)控件基类TemplatedControlControl

  WPF中的UIElementFrameworkElement是非模板控件的基类,大致对应于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属性。StyledPropertyDirectProperty的共同基类是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这样的控件中,相同的代码将导致不同的渲染行为:

posted @ 2024-07-24 12:00  ꧁执笔小白꧂  阅读(187)  评论(0编辑  收藏  举报