【问题标题】:Bind and update ObservableCollection<T> to MenuFlyoutSubItem绑定并更新 ObservableCollection<T> 到 MenuFlyoutSubItem
【发布时间】:2016-09-11 18:17:18
【问题描述】:

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

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: c# .net list uwp observablecollection


    【解决方案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);
                      }
                  }));
      }
      

    这是完整的演示:MenuFlyoutSubItemBindingSample

    【讨论】:

      【解决方案2】:

      我已经尝试了@Elvis Xia - MSFT 的建议,虽然它对我不起作用,但它向我展示了解决方案的方法。我在其中一个自动生成的 .cs 文件中遇到编译错误(使用 x:Bind),说它无法从 MenuFlyout 转换为 FrameworkElement。当我改用“绑定”时,我设法编译,但菜单没有更新。所以,我所做的只是将依赖属性向上移动一级(或两级,如果你考虑&lt;Button.Flyout&gt;),到按钮本身:

      <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; }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-02
        • 1970-01-01
        • 1970-01-01
        • 2011-07-26
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多