为什么MenuFlyout.Items在Closing事件中始终为null,无法删除动态添加的菜单项?
问题根源
- 筛选匹配逻辑错误:你在动态创建
MenuFlyoutItem时仅设置了Text属性为Resolve Conflict,没有给Name属性赋值,但在Closing事件中使用o.Name == "Resolve Conflict"作为筛选条件,自然永远找不到对应元素,你误以为Items集合为null,实际集合本身是存在的,只是没有匹配到符合条件的元素。 - 若确实出现
Items为null的极端情况,还有一种可能是MenuFlyout作为页面静态资源,在Closing事件触发的生命周期节点,临时和可视化树解绑导致上下文异常,但这种情况出现概率极低,核心问题还是前者。
修复方案
修改两处代码即可:
- 要么动态创建时给
MenuFlyoutItem设置Name属性,要么把Closing事件的筛选条件改为匹配Text属性,这里推荐直接匹配Text更简单。 - 补充
Opening事件的防重复添加判断,避免多次右键后重复添加相同菜单项。
修改后的ViewModel代码如下:
public void ContextMenuFlyout_Opening(object sender, object e) { MenuFlyout flyout = sender as MenuFlyout; if (flyout != null) { // 先判断是否已经存在对应菜单项,避免重复添加 var existItem = flyout.Items.FirstOrDefault(o => o is MenuFlyoutItem item && item.Text == "Resolve Conflict"); if (existItem != null) { return; } // 若party.IsConflict = true则添加对应菜单项 if (SelectedTalent.IsConflict) { flyout.Items.Add(new MenuFlyoutItem() { Icon = new FontIcon() { Glyph = "\uEC4F" }, Text = "Resolve Conflict" }); } } } public void ContextMenuFlyout_Closing(object sender, object e) { // 若存在Resolve Conflict菜单项则执行删除 MenuFlyout flyout = sender as MenuFlyout; if (flyout != null) { // 改为匹配Text属性 var rc = flyout.Items.FirstOrDefault(o => o is MenuFlyoutItem item && item.Text == "Resolve Conflict"); if (rc != null) { flyout.Items.Remove(rc); } } }
额外优化建议
因为你的MenuFlyout是放在Page.Resources中的静态资源,会被所有ListView项共用,如果你不想每次打开关闭都增删节点,也可以提前在XAML中定义好这个Resolve Conflict菜单项,默认设置Visibility = Collapsed,在Opening事件中根据SelectedTalent.IsConflict的值切换可见性即可,性能更优。
内容的提问来源于stack exchange,提问作者tinmac
相关产品推荐
相关产品推荐

