最近重写旧项目,发现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 等多平台。