问题
Currently I get "The property "Items" does not have an accessible setter." How could I modify this control to allow me to bind a collection to it and maybe just set on of the properties of the objects in the collection to the text property of the items?
<AppBarButton x:Name="Button" Icon="Add" Label="stuff">
<AppBarButton.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="b1" ></MenuFlyoutItem>
<MenuFlyoutItem Text="b2" ></MenuFlyoutItem>
<MenuFlyoutItem Text="b3" ></MenuFlyoutItem>
<MenuFlyoutItem Text="b4" ></MenuFlyoutItem>
<MenuFlyoutItem Text="b5" ></MenuFlyoutItem>
<MenuFlyoutSubItem x:Name="bb1" Items="{Binding MyList}" />
</MenuFlyout>
</AppBarButton.Flyout>
</AppBarButton>
回答1:
You cannot do this. If you take a look at documentation, you will see that Items has only a getter, so cannot set collection to it. You can get collection reference and then for example Add items to it, but it seems that this works until the flyout is shown. After that no changes are applied (though I don't have much time now to play with it). Here is some code, where I've tried something with attached property:
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Content="click">
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="b1"/>
<MenuFlyoutItem Text="b2"/>
<MenuFlyoutSubItem Name="mysub" local:MenuExtension.MyItems="{Binding Options}" Text="Choosable items"/>
</MenuFlyout>
</Button.Flyout>
</Button>
<Button Content="modify" Click="Button_Click"/>
</StackPanel>
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);
}));
}
public sealed partial class MainPage : Page,INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public List<MenuFlyoutItem> Options { get; set; } = new List<MenuFlyoutItem>
{
new MenuFlyoutItem {Text="Start item" },
new MenuFlyoutItem {Text="Start item" },
new MenuFlyoutItem {Text="Start item" }
};
public MainPage()
{
this.InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Options = new List<MenuFlyoutItem> { new MenuFlyoutItem { Text = "Modified" } };
RaiseProperty(nameof(Options));
// mysub.Items.Add(new MenuFlyoutItem { Text = "modified" }); // even this cannot be done
}
}
Maybe you can play with some templates, bind in button and then exchange the whole flyout, or try something different
来源:https://stackoverflow.com/questions/33839279/bind-obserable-collection-to-menuflyoutsubitem-in-uwp