绑定并更新ObservableCollection
本文关键字:MenuFlyoutSubItem ObservableCollection 更新 绑定 | 更新日期: 2023-09-27 18:06:30
我正在Visual Studio 2015中开发一个UWP(通用Windows平台)应用程序。我现在面临的问题是我想在一个MenuFlyoutSubItem
中添加项目。基本上,这些项目是播放列表的集合。
我的问题是:如何将ObservableCollection
或List
绑定到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,那么它将更新,但我不知道如何实现此行为。
如果在每个弹出窗口上再次创建Flyout,那么它将更新,但我不知道如何实现此行为。
你是对的,我删除了MenuFlyout
的所有项目,重新添加。弹出框被更新了。直接更新MenuFlyoutSubItem
的子项对surface没有任何影响
你可以像下面这样修改代码:
-
在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>
-
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));
}
}
-
修改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; }
本文关键字:MenuFlyoutSubItem ObservableCollection 更新 绑定 | 更新日期: 2023-09-27 18:06:30
我正在Visual Studio 2015中开发一个UWP(通用Windows平台)应用程序。我现在面临的问题是我想在一个MenuFlyoutSubItem
中添加项目。基本上,这些项目是播放列表的集合。
我的问题是:如何将ObservableCollection
或List
绑定到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,那么它将更新,但我不知道如何实现此行为。
如果在每个弹出窗口上再次创建Flyout,那么它将更新,但我不知道如何实现此行为。
你是对的,我删除了MenuFlyout
的所有项目,重新添加。弹出框被更新了。直接更新MenuFlyoutSubItem
的子项对surface没有任何影响
你可以像下面这样修改代码:
-
在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>
-
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)); } }
-
修改
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); } })); }
我尝试了@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; }