Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

winrt xaml - Why doesn't the Windows 8.1 MenuFlyout have ItemsSource property?

I was reading this article and could not help but wonder the same thing.

Is there a way to databind a menu Flyout control?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes.

I put together a simple solution for developers who desire this functionality. It uses an attached property to identify the ItemsSource and the ItemTemplate for a Flyout control. If the developer elects to use a MenuFlyoutItem or something else, it is up to them.

Here's the attached property:

public class BindableFlyout : DependencyObject
{
    #region ItemsSource

    public static IEnumerable GetItemsSource(DependencyObject obj)
    {
        return obj.GetValue(ItemsSourceProperty) as IEnumerable;
    }
    public static void SetItemsSource(DependencyObject obj, IEnumerable value)
    {
        obj.SetValue(ItemsSourceProperty, value);
    }
    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.RegisterAttached("ItemsSource", typeof(IEnumerable),
        typeof(BindableFlyout), new PropertyMetadata(null, ItemsSourceChanged));
    private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    { Setup(d as Windows.UI.Xaml.Controls.Flyout); }

    #endregion

    #region ItemTemplate

    public static DataTemplate GetItemTemplate(DependencyObject obj)
    {
        return (DataTemplate)obj.GetValue(ItemTemplateProperty);
    }
    public static void SetItemTemplate(DependencyObject obj, DataTemplate value)
    {
        obj.SetValue(ItemTemplateProperty, value);
    }
    public static readonly DependencyProperty ItemTemplateProperty =
        DependencyProperty.RegisterAttached("ItemTemplate", typeof(DataTemplate),
        typeof(BindableFlyout), new PropertyMetadata(null, ItemsTemplateChanged));
    private static void ItemsTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    { Setup(d as Windows.UI.Xaml.Controls.Flyout); }

    #endregion

    private static async void Setup(Windows.UI.Xaml.Controls.Flyout m)
    {
        if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
            return;
        var s = GetItemsSource(m);
        if (s == null)
            return;
        var t = GetItemTemplate(m);
        if (t == null)
            return;
        var c = new Windows.UI.Xaml.Controls.ItemsControl
        {
            ItemsSource = s,
            ItemTemplate = t,
        };
        var n = Windows.UI.Core.CoreDispatcherPriority.Normal;
        Windows.UI.Core.DispatchedHandler h = () => m.Content = c;
        await m.Dispatcher.RunAsync(n, h);
    }
}

And, here's sample usage.

<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton Label="AppBarButton">
            <AppBarButton.Flyout>
                <Flyout local:BindableFlyout.ItemsSource="{Binding MenuItems}">
                    <local:BindableFlyout.ItemTemplate>
                        <DataTemplate>
                            <MenuFlyoutItem Text="{Binding Text}" />
                        </DataTemplate>
                    </local:BindableFlyout.ItemTemplate>
                </Flyout>
            </AppBarButton.Flyout>
            <AppBarButton.Icon>
                <SymbolIcon/>
            </AppBarButton.Icon>
        </AppBarButton>
    </CommandBar>
</Page.BottomAppBar>

I will be maintaining this code here.

Looks like this:

enter image description here

I hope this helps you.

Best of luck!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...