这可能是一个简单的解决方案-只是解释起来有点长。
我在运行时将自定义列表视图项添加到ListView。每个ListView项都有一个Name,一个布尔值和一个按钮。单击按钮时会显示一个弹出菜单,其中包含子项菜单,如图所示。子项菜单应该只显示所有其他项的名称,而不显示其本身。正确的行为如第一张图中的“项4”所示单击菜单按钮后,我们只能看到子菜单中列出的项目0到3。
问题是,如果我导航到一个子菜单,然后在列表框中添加新项目,则新项目永远不会出现在以前导航到的旧项目的子菜单中。就像下图中一样,我单击了“项目1”按钮,但只列出了项目0和项目2,由于某种原因,项目3和项目4没有列出。
首先,有一个完整的最低VS 2019解决方案演示了行为我在上面描述了GitHub here,但我已经总结了我认为是代码的关键位如下。
非锅炉板XAML标题(MainPage.Xaml)
xmlns:local="using:DynamicFlyoutMenuTest.ViewModels"
主ListView定义及其DataTemplate以及用于在运行时添加ListView项的按钮:
<StackPanel>
<Button Name="AddCustomListItemBtn" Click="AddCustomListItemBtn_Click">Add Custom ListItem</Button>
<ListView
Name="LayerListBox"
Height="Auto"
BorderBrush="{ThemeResource SystemBaseLowColor}"
BorderThickness="1.0"
ItemsSource="{x:Bind ViewModel.MyCustomListItems}">
<ListView.HeaderTemplate>
<DataTemplate>
<Grid Padding="2" Background="{ThemeResource SystemBaseLowColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="190" />
<ColumnDefinition Width="132" />
</Grid.ColumnDefinitions>
<TextBlock Style="{ThemeResource CaptionTextBlockStyle}" Text="Name" />
<TextBlock
Grid.Column="1"
Style="{ThemeResource CaptionTextBlockStyle}"
Text="Active" />
</Grid>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:Name="TableDataTemplate" x:DataType="local:MyCustomListItem">
<Grid Height="48" AutomationProperties.Name="{x:Bind ItemName}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="190" />
<ColumnDefinition Width="132" />
<ColumnDefinition Width="132" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Padding="10"
VerticalAlignment="Center"
Text="{x:Bind ItemName, Mode=OneWay}" />
<CheckBox
Grid.Column="1"
VerticalAlignment="Center"
IsChecked="{x:Bind isEditing, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button
Name="exportLayerButton"
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<Button.Flyout>
<MenuFlyout Opening="MenuFlyout_Opening">
<MenuFlyoutItem
Name="Action1Btn"
Click="Action1Btn_Click"
Text="Action 1" />
<MenuFlyoutItem
Name="Action2Btn"
Click="Action2Btn_Click"
Text="Action 2" />
<MenuFlyoutSubItem x:Name="SubActionsBtn" Text="Choose Sub Action">
<MenuFlyoutItem Name="NoSubActionBtn" Text="None" />
</MenuFlyoutSubItem>
</MenuFlyout>
</Button.Flyout>
<Polygon
Fill="Black"
Points="0,0 6,4,0,8"
Stroke="Black" />
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
MainPage.xaml.cs -将项目添加到列表和更新弹出子菜单项
private void MenuFlyout_Opening(object sender, object e)
{
//make MenuFlyoutSubItem list all Items in ListView except the one triggering this function
var menuFlyout = sender as MenuFlyout;
// get the menu list we want to add to
MenuFlyoutSubItem menuSubItems = menuFlyout.Items.Where(x => x.Name == "SubActionsBtn").FirstOrDefault() as MenuFlyoutSubItem;
// get the active maplayerlistitem (that triggered this menu opening event)
MyCustomListItem myCustomListItem = (menuFlyout.Target as Button).DataContext as MyCustomListItem;
menuSubItems.Items.Clear();
foreach (var targetItem in ViewModel.MyCustomListItems)
{
if (myCustomListItem.ItemName != targetItem.ItemName)
{
var tItem = new MenuFlyoutItem();
tItem.Text = targetItem.ItemName.ToString();
//tItem.Click += new Windows.UI.Xaml.RoutedEventHandler(DoSomethingBtn_Click);
menuSubItems.Items.Add(tItem);
}
}
}
private void AddCustomListItemBtn_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
// Update ListView
var newItem = new MyCustomListItem();
newItem.ItemName = "Item " + ViewModel.MyCustomListItems.Count.ToString();
newItem.isEditing = false;
ViewModel.MyCustomListItems.Add(newItem);
}
MainViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Microsoft.Toolkit.Mvvm.ComponentModel;
namespace DynamicFlyoutMenuTest.ViewModels
{
public class MainViewModel : ObservableObject
{
public ObservableCollection<MyCustomListItem> MyCustomListItems = new ObservableCollection<MyCustomListItem>();
public MainViewModel()
{
}
}
public class MyCustomListItem : INotifyPropertyChanged
{
public MyCustomListItem()
{
}
private bool _isEditing;
public bool isEditing
{
get { return _isEditing; }
set
{
_isEditing = value;
NotifyPropertyChanged(this, "isEditing");
}
}
private string _itemName;
public string ItemName
{
get { return _itemName; }
set
{
_itemName = value;
NotifyPropertyChanged(this, "ItemName");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(object sender, string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(sender, e);
}
}
}
}
型
EDIT您可以在https://www.youtube.com/watch?v=yPNNtsS-n5Q查看视频中的问题您可以通过以下方式从GitHub源代码重现该问题
1.使用“添加......”按钮向列表视图添加3个项目。
1.导航到每个ListViewItem的子菜单弹出型按钮
1.使用“添加...”按钮再添加2个列表视图项目
1.导航到两个新项目的子菜单弹出按钮,最后
1.导航到原始3个项目的子菜单Flyout,看到它们没有更新以反映添加的附加ListView项目。
1条答案
按热度按时间dba5bblo1#
我找到了一个变通方法,删除了现有的MenuFlyoutSubItem,并在每次打开Flyout时添加一个新的。所以这不是很理想,但确实有效。
如果有人有一个实际的解决方案,我很乐意标记为这样。
否则,解决方法如下: