绑定并更新ObservableCollection

本文关键字:MenuFlyoutSubItem ObservableCollection 更新 绑定 | 更新日期: 2023-09-27 18:06:30

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

我的问题是:如何将ObservableCollectionList绑定到MenuFlyoutSubItem,并在添加新项时更新项?我已经从这里尝试过了:将可观察集合绑定到UWP中的MenuFlyoutSubItem

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将改变。我如何添加更新到这个扩展?如果在每个弹出窗口上再次创建Flyout,那么它将更新,但我不知道如何实现此行为。

绑定并更新ObservableCollection<MenuFlyoutSubItem

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

你是对的,我删除了MenuFlyout的所有项目,重新添加。弹出框被更新了。直接更新MenuFlyoutSubItem的子项对surface没有任何影响

你可以像下面这样修改代码:

  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. Init/update MenuFlyout item in code-behind:

    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);
                    }
                }));
    }
    
下面是完整的演示:MenuFlyoutSubItemBindingSample

我尝试了@Elvis Xia - MSFT的建议,虽然它对我不起作用,但它向我展示了解决问题的方法。我在一个自动生成的。cs文件中得到了一个编译错误(使用x:Bind),说它无法从MenuFlyout转换为FrameworkElement。当我使用"Binding"代替时,我成功编译了,但菜单没有更新。因此,我所做的只是将依赖属性向上移动一级(或者2级,如果您考虑<Button.Flyout>),到按钮本身:

<Button local:ButtonExtension.MenuFlyout="{x:Bind MainViewModel.Menu, Mode=OneWay}"/>
下面是ButtonExtension类:
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);
    }
}

这是ViewModel中的属性:

public MenuFlyout Menu { get; private set; }

相关文章:
  • 没有找到相关文章