WinUI 3 DropDownButton 数据绑定

问题描述 投票:0回答:1

如何将 DropDownButton 的项目绑定到 ViewModel?

<DropDownButton Width="100" Grid.Column="2" ToolTipService.ToolTip="Language">
    <TextBlock FontSize="14" Text="Select language"/>
    <DropDownButton.Flyout>
        <MenuFlyout Placement="BottomEdgeAlignedLeft">
            <MenuFlyoutItem Text="English" Tag="enEn" Click="DropdownOptionLanguage_Select" />
        </MenuFlyout>
    </DropDownButton.Flyout>
</DropDownButton>

如果我们遵循这里的逻辑,

MenuFlyout
DropDownButton.Flyout
是项目的容器。但是没有
ItemSource
属性或我可以绑定到枚举的东西。

c# xaml winui-3 winui community-toolkit-mvvm
1个回答
1
投票

在这种情况下,您可以在代码隐藏中添加项目:

主页.xaml

<DropDownButton Content="Select language">
    <DropDownButton.Flyout>
        <MenuFlyout x:Name="SelectLanguageMenuLayout" />
    </DropDownButton.Flyout>
</DropDownButton>
public enum Languages
{
    English,
    Spanish,
    French,
    German,
    Italian,
}
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        foreach (Languages language in Enum.GetValues<Languages>())
        {
            this.SelectLanguageMenuLayout.Items.Add(
                new MenuFlyoutItem
                {
                    Text = language.ToString(),
                    Command = ViewModel.ChangeLanguageCommand,
                    CommandParameter = language,
                });
        }
    }

    public MainPageViewModel ViewModel { get; } = new();
}
public partial class MainPageViewModel : ObservableObject
{
    [RelayCommand]
    private void ChangeLanguage(Languages language)
    {
    }
}

我正在使用 CommunityToolkit.Mvvm NuGet 包进行 MVVM 设计。

更新

这应该更接近您在评论中提到的内容:

MenuFlyoutEx.cs

public class MenuFlyoutEx : MenuFlyout
{
    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            nameof(ItemsSource),
            typeof(IEnumerable),
            typeof(MenuFlyoutEx),
            new PropertyMetadata(default, OnItemsSourcePropertyChanged));

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register(
            nameof(Command),
            typeof(ICommand),
            typeof(MenuFlyoutEx),
            new PropertyMetadata(default));

    public IEnumerable ItemsSource
    {
        get => (IEnumerable)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public ICommand Command
    {
        get => (ICommand)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not MenuFlyoutEx menuFlyoutEx ||
            e.NewValue is not IEnumerable itemsSource)
        {
            return;
        }

        menuFlyoutEx.Items.Clear();

        foreach (object item in itemsSource)
        {
            MenuFlyoutItem menuFlyoutItem = new()
            {
                Text = item.ToString(),
                Command = menuFlyoutEx.Command,
                CommandParameter = item,
            };

            menuFlyoutEx.Items.Add(menuFlyoutItem);
        }
    }
}

MainPageViewModel.cs

// This class needs to be "partial" for the CommunityToolkit.Mvvm.
public partial class MainPageViewModel : ObservableObject
{
    // The CommunityToolkit.Mvvm will generate a "ChangeLanguageCommand" for you.
    [RelayCommand]
    private void ChangeLanguage(Languages language)
    {
        // Do your logic here...
    }

    // The CommunityToolkit.Mvvm will generate a "LanguageOptions" property for you.
    [ObservableProperty]
    private Languages[] _languageOptions = Enum.GetValues<Languages>();
}

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public MainPageViewModel ViewModel { get; } = new();
}

并像这样使用它:

<DropDownButton Content="Select language">
    <DropDownButton.Flyout>
        <local:MenuFlyoutEx
            Command="{x:Bind ViewModel.ChangeLanguageCommand}"
            ItemsSource="{x:Bind ViewModel.LanguageOptions}" />
    </DropDownButton.Flyout>
</DropDownButton>
© www.soinside.com 2019 - 2024. All rights reserved.