Maui:通过附加属性将命令绑定到事件
最近重写旧项目,发现maui的社区工具EventToCommand不起作用,没发现问题在哪?也懒得重新安装包,自己模仿Avalonia写一个附加属性执行命令。
using System.Windows.Input;
namespace FileNexus.Behaviours
{
public static class LoadedBehavious
{
public static readonly BindableProperty LoadedCommandProperty = BindableProperty.CreateAttached("LoadedCommand", typeof(ICommand),
typeof(LoadedBehavious), null, BindingMode.OneWay, propertyChanged: OnLoadedCommandChanged);
private static void OnLoadedCommandChanged(BindableObject bindable, object oldValue, object newValue)
{
if(bindable is VisualElement element)
{
if(newValue is ICommand command)
{
element.Loaded += Handler;
}
else
{
element.Loaded -= Handler;
}
}
}
public static ICommand GetLoadedCommand(BindableObject bindable)
{
return (ICommand)bindable.GetValue(LoadedCommandProperty);
}
public static void SetLoadedCommand(BindableObject bindable,ICommand command)
{
bindable.SetValue(LoadedCommandProperty, command);
}
private static void Handler(object? sender, EventArgs e)
{
if(sender is VisualElement visualElement)
{
ICommand command = (ICommand)visualElement.GetValue(LoadedCommandProperty);
if (command.CanExecute(null))
{
command.Execute(null);
}
}
}
}
}
xaml平台
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:b="clr-namespace:FileNexus.Behaviours"
b:LoadedBehavious.LoadedCommand="{Binding InitCommand}"
x:Class="FileNexus.Views.FileCollectionPage"
Title="文件列表" BackgroundColor="Teal" NavigatedTo="ContentPage_NavigatedTo">
<ContentPage.ToolbarItems>
<ToolbarItem Text="删除" Command="{Binding RemoveItemCommand}"/>
<ToolbarItem Text="发文" Command="{Binding SendTextCommand}"/>
<ToolbarItem Text="回退" Command="{Binding GoBackCommand}"/>
</ContentPage.ToolbarItems>
<Grid RowDefinitions="Auto,Auto,Auto,*" Padding="10">
<ActivityIndicator IsRunning="{Binding IsUploading}" IsVisible="{Binding IsUploading}" Color="Orange" Grid.Row="0"/>
<Label Text="{Binding CurrentDirectory,StringFormat='当前路径:{0}'}" TextColor="White" FontSize="16" FontAttributes="Bold" Grid.Row="1"/>
<Label Text="{Binding WebFiles.Count,StringFormat='项目数:{0}'}" TextColor="White" FontSize="16" Grid.Row="2"/>
<SwipeView Grid.Row="3">
<SwipeView.LeftItems>
<SwipeItem Text="上传" BackgroundColor="Orange" Command="{Binding UploadCommand}"/>
<SwipeItem Text="下载" BackgroundColor="Chocolate" Command="{Binding DownloadCommand}"/>
</SwipeView.LeftItems>
<CollectionView ItemsSource="{Binding WebFiles}" SelectionMode="Single" SelectionChangedCommand="{Binding SelectedItemCommand}"
SelectionChangedCommandParameter="{Binding Source={RelativeSource Self},Path=SelectedItem}" x:Name="collectionView">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" ItemSpacing="5"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="Auto,*" RowDefinitions="*,*" RowSpacing="2" ColumnSpacing="10">
<Image Source="documents.png" Aspect="AspectFill" Grid.Row="0" Grid.Column="0" WidthRequest="48" HeightRequest="48" Grid.RowSpan="2">
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding IsDirectory}" Value="True">
<Setter Property="Source" Value="folder.png"/>
</DataTrigger>
</Image.Triggers>
</Image>
<Label Text="{Binding FileName}" TextColor="White" Grid.Column="1" Grid.Row="0" FontSize="16" FontAttributes="Bold"/>
<Label Text="{Binding LastModifiedTime,StringFormat='修改时间:{0:yyyy-MM-dd HH:mm:ss}'}" Grid.Column="1" Grid.Row="1" TextColor="White">
<Label.Triggers>
<DataTrigger TargetType="Label" Binding="{Binding IsDirectory}" Value="True">
<Setter Property="Text" Value="{Binding CreationTime,StringFormat='创建时间:{0:yyyy-MM-dd HH:mm:ss}'}"/>
</DataTrigger>
</Label.Triggers>
</Label>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</SwipeView>
</Grid>
</ContentPage>
MAUI 附加属性与 Avalonia 的关键差异对比
虽然核心逻辑一致,但 MAUI 和 Avalonia 的附加属性在实现细节上有 3 处关键差异,需注意适配:
对比维度 | MAUI | Avalonia |
---|---|---|
基类 | 基于BindableObject | 基于AvaloniaObject |
附加属性注册方法 | BindableProperty.CreateAttached | AvaloniaProperty.RegisterAttached |
控件加载事件 | VisualElement.Loaded | 用Control.LoadedEvent |
MAUI 不仅支持创建附加属性,而且实现逻辑与 Avalonia 高度相似 —— 都是通过 “静态属性 + 事件关联 + 数据绑定” 扩展控件功能。只需注意 MAUI 基于BindableObject的语法细节,即可实现与文章中 Avalonia 相同的 “事件绑定命令” 等场景,甚至可复用到 Android、iOS、Windows 等多平台。