将ObservableCollection <t>绑定并更新为MenuFlyoutSubItem

时间:2016-09-11 18:17:18

标签: c# .net list uwp observablecollection

我正在Visual Studio 2015中开发一个UWP(通用Windows平台)应用程序。我目前正面临这个问题,我想将项目添加到MenuFlyoutSubItem。基本上,这些项目是播放列表的集合。

我的问题是: 如何将ObservableCollectionList绑定到MenuFlyoutSubItem并在添加新项目时更新项目?我已经从这里尝试了这个:Bind Obserable Collection to MenuFlyoutSubItem in UWP

public static class MenuExtension
{
public static List<MenuFlyoutItem> GetMyItems(DependencyObject obj)
{ return (List<MenuFlyoutItem>)obj.GetValue(MyItemsProperty); }

public static void SetMyItems(DependencyObject obj, List<MenuFlyoutItem> value)
{ obj.SetValue(MyItemsProperty, value); }

public static readonly DependencyProperty MyItemsProperty =
    DependencyProperty.Register("MyItems", typeof(List<MenuFlyoutItem>), typeof(MenuExtension),
    new PropertyMetadata(new List<MenuFlyoutItem>(), (sender, e) =>
    {
        Debug.WriteLine("Filling collection");
        var menu = sender as MenuFlyoutSubItem;
        menu.Items.Clear();
        foreach (var item in e.NewValue as List<MenuFlyoutItem>) menu.Items.Add(item);
    }));

}

只要项目不变,但在我的方案中Items会发生变化,这是好事。如何向此扩展程序添加更新?如果在每个弹出窗口中再次创建弹出窗口,那么它将更新,但我不知道如何实现此行为。

任何帮助都将受到高度赞赏,谢谢。

2 个答案:

答案 0 :(得分:1)

  

如果在每个弹出窗口上再次创建Flyout,那么它将更新,但我不知道如何实现此行为。

你是对的,我删除了MenuFlyout的所有项目并重新添加。弹出窗口已更新。直接更新MenuFlyoutSubItem的子项对表面没有任何影响。

为此,您可以修改如下代码:

  1. 在XAML中将项目绑定到MenuFlyout而不是MenuFlyoutSubItem

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalAlignment="Center">
            <Button Content="click" Name="myBtn">
                <Button.Flyout>
                    <MenuFlyout local:FlyoutMenuExtension.MyItems="{Binding OptionItems}">
                    </MenuFlyout>
            </Button.Flyout>
        </Button>
        <Button Content="modify" Click="Button_Click"/>
    </StackPanel>
    
  2. 初始化/更新代码隐藏中的MenuFlyout项:

    public sealed partial class MainPage : Page,INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    
        public List<MenuFlyoutItemBase> OptionItems { get; set; }
    
        public List<MenuFlyoutItemBase> InitFlyoutItems()
        {
            var list = new List<MenuFlyoutItemBase>
            {
                new MenuFlyoutItem {Text="Start item 1" },
                new MenuFlyoutItem {Text="Start item 2" },
                new MenuFlyoutItem {Text="Start item 3" },
                new MenuFlyoutSubItem { Text="Start Item 4"  }
            };
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "Old Sub Item 1" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "Old Sub Item 2" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "Old Sub Item 3" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "Old Sub Item 4" });
            return list;
        }
    
        public List<MenuFlyoutItemBase> UpdateFlyoutItems()
        {
            var list = new List<MenuFlyoutItemBase>
            {
                new MenuFlyoutItem {Text="Start item 1" },
                new MenuFlyoutItem {Text="Start item 2" },
                new MenuFlyoutItem {Text="Start item 3" },
                new MenuFlyoutSubItem { Text="Start Item 4"  }
            };
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "New Sub Item 1" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "New Sub Item 2" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "New Sub Item 3" });
            ((MenuFlyoutSubItem)list[3]).Items.Add(new MenuFlyoutItem { Text = "New Sub Item 4" });
            return list;
        }
    
        public MainPage()
        {
            this.InitializeComponent();
            DataContext = this;
        }
    
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            OptionItems = InitFlyoutItems();
            RaiseProperty(nameof(OptionItems));
            base.OnNavigatedTo(e);
        }
    
    
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            OptionItems=UpdateFlyoutItems();
            RaiseProperty(nameof(OptionItems));
        }
    }
    
  3. 修改MenuExtension

    public static class FlyoutMenuExtension
    {
        public static List<MenuFlyoutItemBase> GetMyItems(DependencyObject obj)
        {
            return (List<MenuFlyoutItemBase>)obj.GetValue(MyItemsProperty);
        }
        public static void SetMyItems(DependencyObject obj, List<MenuFlyoutItemBase> value)
        {
            obj.SetValue(MyItemsProperty, value);
        }
        public static readonly DependencyProperty MyItemsProperty =
            DependencyProperty.Register("MyItems",
                typeof(List<MenuFlyoutItemBase>),
                typeof(FlyoutMenuExtension),
                new PropertyMetadata(new List<MenuFlyoutItemBase>(), (sender, e) => {
                    var menu = sender as MenuFlyout;
                    menu.Items.Clear();
                    foreach (var item in e.NewValue as List<MenuFlyoutItemBase>)
                    {
                        menu.Items.Add(item);
                    }
                }));
    }
    
  4. 以下是完整的演示:MenuFlyoutSubItemBindingSample

答案 1 :(得分:1)

我已经尝试过@Elvis Xia - MSFT建议的内容,虽然它对我没有用,但它向我展示了解决方案的方法。我在其中一个自动生成的.cs文件中遇到了编译错误(使用x:Bind),说它无法从MenuFlyout转换为FrameworkElement。当我使用&#39; Binding&#39;相反,我设法编译,但菜单没有更新。所以,我所做的只是将依赖属性向上移动一级(或两级,如果你考虑<Button local:ButtonExtension.MenuFlyout="{x:Bind MainViewModel.Menu, Mode=OneWay}"/> ),按钮本身:

public static class ButtonExtension
{
    public static readonly DependencyProperty MenuFlyoutProperty =
        DependencyProperty.Register("MenuFlyout",
            typeof(MenuFlyout), typeof(ButtonExtension),
            new PropertyMetadata(new MenuFlyout(), (sender, e) =>
            {
                var button = sender as Button;
                button.Flyout = e.NewValue as MenuFlyout;
            }));

    public static MenuFlyout GetMenuFlyout(DependencyObject obj)
    {
        return (MenuFlyout)obj.GetValue(MenuFlyoutProperty);
    }

    public static void SetMenuFlyout(DependencyObject obj, MenuFlyout value)
    {
        obj.SetValue(MenuFlyoutProperty, value);
    }
}

这里是ButtonExtension类:

public MenuFlyout Menu { get; private set; }

这是ViewModel中的属性:

{{1}}