0

我已经使用社区工具包实现了一个汉堡菜单,它开始很好。我现在正在尝试添加更改菜单中项目的功能。例如,我希望其中一个 OptionItems 显示登录状态。如果没有登录,我希望它说登录,如果他们是,我希望它显示他们的名字。我尝试将标准 x:Bind 添加到标签,但它不起作用:

<controls:HamburgerMenuGlyphItem Label="{x:Bind Path=UserProfileViewModel.UserName}" Tag="SignIn" Glyph="Contact" />

在汉堡菜单外的 TextBlock 上使用完全相同的绑定可以正常工作,用户名一旦登录就会显示。

任何人都知道如何在 MenuItems 中实现绑定?

4

2 回答 2

1

任何人都知道如何在 MenuItems 中实现绑定?

您可以将 HamburgerMenu 的 ItemsSource 设置为 IEnumerable 并绑定到 ItemTemplate 中 T 类型的属性。

看法:

<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d">
<Page.Resources>
    <DataTemplate x:Name="ItemTemplate" x:DataType="local:Item">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="48" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <SymbolIcon Grid.Column="0" Symbol="{x:Bind Symbol}" />
            <TextBlock Grid.Column="1" Text="{x:Bind Label, Mode=TwoWay}" VerticalAlignment="Center" />
        </Grid>
    </DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <controls:HamburgerMenu x:Name="hamburgerMenuControl"
                            ItemsSource="{Binding Items}"
                            SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                            ItemTemplate="{StaticResource ItemTemplate}"
                            ItemClick="hamburgerMenuControl_ItemClick">
        <ContentControl Content="{Binding SelectedItem.Content}" />
    </controls:HamburgerMenu>
</Grid>
</Page>

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = new ViewModel();
    }

    private void hamburgerMenuControl_ItemClick(object sender, ItemClickEventArgs e)
    {
        //workaround to set the SelectedItem property of the view model when a new item is selected
        (DataContext as ViewModel).SelectedItem = e.ClickedItem as Item;
    }
}

查看型号:

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        Items.Add(new Item() { Label = "1", Symbol = Symbol.Bullets, Content = "1..." });
        Items.Add(new Item() { Label = "2", Symbol = Symbol.Bullets, Content = "2..." });
        Items.Add(new Item() { Label = "3", Symbol = Symbol.Bullets, Content = "3..." });
        SelectedItem = Items[0];
    }

    public IList<Item> Items { get; } = new List<Item>();

    private Item _selectedItem;
    public Item SelectedItem
    {
        get { return _selectedItem; }
        set { _selectedItem = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

模型:

public class Item : INotifyPropertyChanged
{
    private string _label;
    public string Label
    {
        get { return _label; }
        set { _label = value; NotifyPropertyChanged(); }
    }

    public Symbol Symbol { get; set; }
    public object Content { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

将模型的 Label 属性设置为用户名或您希望在选项菜单中显示的任何内容。这是使用推荐的 MVVM 设计模式对 HamburgerMenu 进行数据绑定的方式。

如果您直接在视图的 XAML 标记中定义 HamburgerMenuGlyphItems,您可以在同一视图的代码隐藏中以编程方式绑定设置绑定:

<controls:HamburgerMenuGlyphItem x:Name="item" />

public MainPage()
    {
        this.InitializeComponent();

        BindingOperations.SetBinding(item, HamburgerMenuGlyphItem.LabelProperty, 
            new Binding() { Path = new PropertyPath(nameof(Username)), Source = this });
    }

    public string Username { get; } = "username...";
}
于 2016-12-11T16:02:12.453 回答
0

所以mm8提供的解决方案确实有效。然而,在让它发挥作用的过程中,我发现了如何在不付出任何额外努力的情况下解决最初的问题。将 Mode=TwoWay(OneWay 也适用)添加到 DataTemplate 中的 TextBlock 绑定解决了在属性更改时获取标签以更新的问题。然后我发现 HamburgerMenuGlyphItem 本身的数据绑定也需要这个“模式”值设置。一旦我将模式添加到该绑定以及标签在用户登录时开始更新并且根本不需要任何外部代码:)

于 2016-12-12T16:05:52.213 回答