Avalonia与WPF开发时的差异总结

1.一个控件绑定到另外一个控件的属性

WPF:

 <TextBox Height="30" Width="100" x:Name="tb"></TextBox>
 <TextBlock Text="{Binding ElementName=tb,Path=Text}" ></TextBlock>

Avalonia:

<TextBox Height="30" Width="100" x:Name="tb"></TextBox>
<TextBlock Text="{Binding #tb.Text}" ></TextBlock>

当然Avalonia也可以采用WPF的的写法,参考文档

2.列表控件中的元素绑定到ViewModel的DataContext

要实现的效果如下:点击删除操作,能移除元素
在这里插入图片描述
WPF的写法不用介绍了吧。

Avalonia的写法如下:
前端代码:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="clr-namespace:Avalonia_Test.ViewModels"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="Avalonia_Test.Views.MainView"
             x:DataType="vm:MainViewModel">
  <Design.DataContext>
    <!-- This only sets the DataContext for the previewer in an IDE,
         to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
    <vm:MainViewModel />
  </Design.DataContext>
  <UserControl.Styles>
  </UserControl.Styles>
 <StackPanel >
     <DataGrid Name="DG" ItemsSource="{Binding Models}" IsReadOnly="True" AutoGenerateColumns="False">
         <DataGrid.Columns>
             <DataGridTextColumn Header="姓名" Binding="{Binding Name}"></DataGridTextColumn>
             <DataGridTextColumn Header="年龄" Binding="{Binding Age}"></DataGridTextColumn>
             <DataGridTemplateColumn Header="操作" Width="*">
                 <DataGridTemplateColumn.CellTemplate>
                     <DataTemplate>
                         <HyperlinkButton Content="删除" Command="{Binding #DG.((vm:MainViewModel)DataContext).DeleteCmd}" 
                                          CommandParameter="{Binding}"></HyperlinkButton>
                     </DataTemplate>
                 </DataGridTemplateColumn.CellTemplate>
             </DataGridTemplateColumn>
         </DataGrid.Columns>
     </DataGrid>
     
 </StackPanel>
     
  
</UserControl>

后端代码:

public partial class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        DeleteCmd = new RelayCommand<DataGridModel>(Delete);
    }

    private void Delete(DataGridModel? obj)
    {
        if (this.Models.Contains(obj))
        {
            this.Models.Remove(obj);
        }
    }

    [ObservableProperty] private string _greeting = "Welcome to Avalonia!";
    public ObservableCollection<DataGridModel> Models { get; } = new ObservableCollection<DataGridModel>()
    {
        new DataGridModel(){Name = "tony1",Age = 10},
        new DataGridModel(){Name = "tony2",Age = 20},
        new DataGridModel(){Name = "tony3",Age = 30},
        new DataGridModel(){Name = "tony4",Age = 40},
    };

    public RelayCommand<DataGridModel> DeleteCmd { get; }
}

其中关键的一句<HyperlinkButton Content="删除" Command="{Binding #DG.((vm:MainViewModel)DataContext).DeleteCmd}" CommandParameter="{Binding}">
将命令绑定到ViewModel的DeleteCmd。

属性触发器

WPF中使用Trigger,Avalonia中使用伪类或者样式选择器

例如实现一个CheckBox勾选时,前景色为红色。

WPF的实现方式:

<Window.Resources>
    <Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Foreground" Value="Red"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <CheckBox Height="30" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">Test Test</CheckBox>
</Grid>

最后效果:
在这里插入图片描述
Avalonia的实现方式:

<Window.Styles>
   <Style Selector="CheckBox[IsChecked=True]">
        <Setter Property="Foreground" Value="Red"></Setter>
    </Style>
</Window.Styles>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
    <CheckBox Height="30" Width="100">Test Test</CheckBox>
</Grid>

最后实现的效果:
在这里插入图片描述

数据触发器

WPF有专门的数据触发器
Avalonia没有,那么要实现数据触发功能怎么办呢?
据我现在所知,只能使用转换器

样式

Avalonia样式介绍:https://docs.avaloniaui.net/zh-Hans/docs/get-started/wpf/styling

归纳起来就是:

  • WPF的样式作用于同一个控件是相互覆盖的,无论属性设置值是否相同。
    例如,有两个样式,style1设置按钮背景色红色,style2设置前景色为绿色。当style1和style2都作用与一个按钮时,只会出现后作用的样式生效,后来作用的样式会清除之前的样式。

WPF的覆盖效果如下:

<Window.Resources>
    <Style TargetType="CheckBox">
        <Setter Property="Foreground" Value="Red"></Setter>
    </Style>
</Window.Resources>
<Grid>
    <CheckBox Height="30" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="Test Test">
        <CheckBox.Style>
            <Style TargetType="CheckBox">
                <Setter Property="Background" Value="Blue"></Setter>
            </Style>
        </CheckBox.Style>
    </CheckBox>
</Grid>

在这里插入图片描述
只是背景色变蓝,而前景色不变。
当然可以使用BasedOn来实现样式继承

  • Avalonia的样式Style是相互叠加的,ControlTheme是相互覆盖的。

Avalonia样式的叠加效果如下:

<Window.Styles>
   <Style Selector="CheckBox">
        <Setter Property="Foreground" Value="Red"></Setter>
    </Style>
    <Style Selector="CheckBox">
        <Setter Property="Background" Value="Blue"></Setter>
    </Style>
</Window.Styles>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
    <CheckBox Height="30" Width="100">Test Test</CheckBox>
</Grid>

在这里插入图片描述
结合以上案例及文档,大概得出如下结论:
Avalonia的ControlTheme与WPF的Style相似。
Avalnia增加Style配合Selector使样式设置更为灵活

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值