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
使样式设置更为灵活