我在 .NET MAUI 中使用 CollectionView,以便动态添加按钮,因此能够动态更改按钮的顺序。
为此,我创建了一个 ButtonObject 模型:
public class ButtonObject
{
public string? ButtonText { get; set; }
public IRelayCommand? ButtonCommand { get; set; }
public bool? ButtonIsVisible { get; set; }
public string? ButtonGlyph { get; set; }
}
此模型用于在 ViewModel 中创建按钮:
public partial class TestViewModel
{
[ObservableProperty]
private ObservableCollection<ButtonObject> _buttons = new();
private ButtonObject _testButton;
[ObservableProperty]
private string _testGlyph = IconFont.Add;
public TestViewModel()
{
_testButton = new ButtonObject()
{
ButtonText = "Title",
ButtonCommand = PerformActionCommand,
ButtonIsVisible = true,
ButtonGlyph = TestGlyph,
};
_buttons.Add(_testButton);
}
[RelayCommand]
private void OnPerformAction()
{
//...
}
}
View 使用 CollectionView 来显示按钮:
<CollectionView ItemsSource="{Binding Buttons}"
ItemsLayout="HorizontalList"
SelectionMode="None"
ItemSizingStrategy="MeasureFirstItem">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="20">
<Button MaximumWidthRequest="150"
x:DataType="models:ButtonObject"
Text="{x:Binding ButtonText}"
Command="{x:Binding ButtonCommand}"
IsVisible="{x:Binding ButtonIsVisible}">
<Button.ImageSource>
<FontImageSource FontFamily="MSO"
Glyph="{x:Binding ButtonGlyph}"
Size="20" />
</Button.ImageSource>
</Button>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
但是,该字形在 CollectionView 中不可见。
关于图标: ViewModel 从单独的类中获取图标信息:
public static class IconFont
{
public const string Add = "\ue145";
// many more...
}
FontFamily 来自 Google 的 Material Icons:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
fonts.AddFont("MaterialIcons-Regular.ttf", "MaterialIconsRegular");
fonts.AddFont("MaterialSymbolsOutlined.ttf", "MSO"); // MSO = Material Symbols Outlined
})
.ConfigureEssentials(essentials =>
{
essentials.UseVersionTracking();
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
}
我尝试直接使用 IconFont 类,它有效:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Project.Views.TestView"
xmlns:helpers="clr-namespace:Project.Helpers"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
<!-- ... -->
<CollectionView ItemsSource="{Binding Buttons}"
ItemsLayout="HorizontalList"
SelectionMode="None"
ItemSizingStrategy="MeasureFirstItem">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="20">
<Button MaximumWidthRequest="150"
x:DataType="models:ButtonObject"
Text="{x:Binding ButtonText}"
Command="{x:Binding ButtonCommand}"
IsVisible="{x:Binding ButtonIsVisible}">
<Button.ImageSource>
<FontImageSource FontFamily="MSO"
Glyph="{x:Static helpers:IconFont.Add}"
Size="20" />
</Button.ImageSource>
</Button>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
有人明白,为什么我有这种奇怪的行为吗?
使用绑定
Glyph="{Binding Source={RelativeSource AncestorType={x:Type ButtonObject}}, Path=ButtonGlyph}"
有效!谢谢@MustafaMutasim