WPF Displaying context menu for GridView's column header when left clicking
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.
精彩评论