开发者

WPF Displaying context menu for GridView's column header when left clicking

开发者 https://www.devze.com 2023-03-23 05:26 出处:网络
I want to display a context menu when a user left clicks a GridView\'s column header. Here\'s my code so far:

I want to display a context menu when a user left clicks a GridView's column header. Here's my code so far:

<GridView>
    <GridViewColumn DisplayMemberBinding="{Binding}">
        <GridViewColumnHeader
            Content="Customer"
            Click="Header_Click"
            >开发者_StackOverflow社区
            <GridViewColumnHeader.ContextMenu>
                <ContextMenu Name="ContextMenu">
                    <MenuItem Header="Sort by Customer" />
                    <MenuItem Header="Sort by Address" />
                </ContextMenu>
            </GridViewColumnHeader.ContextMenu>
        </GridViewColumnHeader>
    </GridViewColumn>
</GridView>

And the code behind:

private void Header_Click(object sender, RoutedEventArgs e)
{
    ContextMenu.IsOpen = true;

    e.Handled = true;
}

Note that GridView is hosted by customized ListView class that has an event listener on GridViewColumnHeader.ClickEvent. However when setting e.Handled on code behind's event listener it stops the event from bubbling upwards.

What my problem is that when clicking the header the context menu just quickly appears on screen and closes right after that. I believe that the header is losing its focus somehow and that's why the context menu is closed. Even setting the StaysOpen property to true won't fix the problem.

Also please note that when right clicking the column header the context menu behaves correctly.

So any suggestion how to stop the context menu from closing?


the problem here is that a mouse click causes several events. In your case either the MouseDown or the MouseUp event (or both) perform the default action for clicking on headers (sorting I guess). I was able to reproduce the behaviour which you described. To fix this behaviour you can register the MouseDown and the MouseUp event and trigger the context menu.

<GridView>
    <GridViewColumn DisplayMemberBinding="{Binding Path=Customers}">
        <GridViewColumnHeader
            Content="Customer"
            MouseDown="GridViewColumnHeader_MouseDown" MouseUp="GridViewColumnHeader_MouseDown">
            <GridViewColumnHeader.ContextMenu>
                <ContextMenu Name="TheContextMenu">
                    <MenuItem Header="Sort by Customer" />
                    <MenuItem Header="Sort by Address" />
                </ContextMenu>
            </GridViewColumnHeader.ContextMenu>
        </GridViewColumnHeader>
    </GridViewColumn>
</GridView>

I use GridViewColumnHeader_MouseDown twice which might be a bit dirty :)

private void GridViewColumnHeader_MouseDown(object sender, MouseButtonEventArgs e)
{
    TheContextMenu.IsOpen = true;
    e.Handled = true;
}

Sort of edit: I've just been playing around a bit. It seems like the MouseUp event is sufficient.

0

精彩评论

暂无评论...
验证码 换一张
取 消