如何将 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
属性或我可以绑定到枚举的东西。
在这种情况下,您可以在代码隐藏中添加项目:
主页.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>