我正在Visual Studio 2015中开发一个UWP(通用Windows平台)应用程序。我目前正面临这个问题,我想将项目添加到MenuFlyoutSubItem
。基本上,这些项目是播放列表的集合。
我的问题是:
如何将ObservableCollection
或List
绑定到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
会发生变化,这是好事。如何向此扩展程序添加更新?如果在每个弹出窗口中再次创建弹出窗口,那么它将更新,但我不知道如何实现此行为。
任何帮助都将受到高度赞赏,谢谢。
答案 0 :(得分:1)
如果在每个弹出窗口上再次创建Flyout,那么它将更新,但我不知道如何实现此行为。
你是对的,我删除了MenuFlyout
的所有项目并重新添加。弹出窗口已更新。直接更新MenuFlyoutSubItem
的子项对表面没有任何影响。
为此,您可以修改如下代码:
在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>
初始化/更新代码隐藏中的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));
}
}
修改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
答案 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}}