.net 当另一个ContextMenu打开时,ContextMenu Close事件不触发

jucafojl  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(192)

我认为我的项目中有错误的逻辑,所以我做了一个新的项目,只有以下内容:

<Window>
<Grid>
    <TreeView>
        <TreeViewItem Header="Test1"/>
        <TreeViewItem Header="Test2"/>
        <TreeViewItem Header="Test3"/>
        <TreeViewItem Header="Test4"/>
        <TreeView.Resources>
            <ContextMenu x:Key="TreeViewContextMenu">
                <MenuItem Header="Click Me!"/>
            </ContextMenu>
            <Style TargetType="TreeViewItem">
                <Setter Property="ContextMenu" Value="{StaticResource TreeViewContextMenu}"/>
                <EventSetter Event="ContextMenuOpening" Handler="TreeViewContextMenu_Opening"/>
                <EventSetter Event="ContextMenuClosing" Handler="TreeViewContextMenu_Closing"/>
            </Style>
        </TreeView.Resources>   
    </TreeView>
</Grid>
</Window>

字符串
当我在ContextMenu开启的情况下按一下鼠标器右击(以开启ContextMenu)时,无论我在ContextMenu、TreeViewItem或TreeView中是否有事件行程常式,都不会触发closing/closed事件。
当按住右键单击或左键单击时,当然不会发生这种情况。
Demonstration的一个。

gcxthw6b

gcxthw6b1#

你知道你让多个TreeViewItem共享一个ContextMenu吗?我看不出有什么好的理由这样做。你的TreeView应该像下面这样修改。

<TreeView>
    <TreeViewItem Header="Test1"/>
    <TreeViewItem Header="Test2"/>
    <TreeViewItem Header="Test3"/>
    <TreeViewItem Header="Test4"/>
    <TreeView.Resources>
        <Style TargetType="TreeViewItem">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Click Me!"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
            <EventSetter Event="ContextMenuOpening" Handler="TreeViewContextMenu_Opening"/>
            <EventSetter Event="ContextMenuClosing" Handler="TreeViewContextMenu_Closing"/>
        </Style>
    </TreeView.Resources>
</TreeView>

字符串

编辑

我在TreeViewContextMenu_Opening事件处理程序中检查了TreeViewItem的ContextMenu示例。

private ContextMenu? _contextMenu;

private void TreeViewContextMenu_Opening(object sender, ContextMenuEventArgs e)
{
    var contextMenu = ((TreeViewItem)sender).ContextMenu;
    Debug.WriteLine($"Opening {contextMenu is not null}  {object.ReferenceEquals(contextMenu, _contextMenu)}");

    _contextMenu = contextMenu;
    _contextMenu.Closed += OnClosed;

    void OnClosed(object sender, RoutedEventArgs e)
    {
        ((ContextMenu)sender).Closed -= OnClosed;
        _contextMenu = null;
        Debug.WriteLine("Closed");
    }
}


我发现,当一个ContextMenu被打开,而一个ContextMenu已经被打开时,ContextMenu的示例是相同的,ContextMenu.Closed事件没有触发。这意味着在这种情况下,相同的ContextMenu被重用。
当然,您将没有机会捕获TreeViewContextMenu_Closing事件,因为ContextMenu不会关闭。

相关问题