ThinkGeo.com    |     Documentation    |     Premium Support

Strange behaviour for wpf ContextMenu - mouse right click not working correctly

 


I am seeing some strange behaviour for wpf ContextMenu. What I am trying to achieve is to have a dynamic ContextMenu generated each time user do a right click on the map. However, there's seems to be some cache mechanism on the ConexteMenu or the map click event. The first time user right click on the map, nothing happens - no ConextMenu is popping up. The second right click will bring up the correct ConextMenu. The third and later right click will bring back the same ContextMenu as teh second click - not updated after the content of the ContextMenu has been updated to show different items.


 


 

Is this a known bug and is there a fix or alternative way to implemente a dynamic ContextMenu?



 

Below is a sample code I have put together to demostrate the strange behaviour.



 

   public partial class Window1 : Window



    {
        int rightClickCount = 0;
 
        public Window1()
        {
            InitializeComponent();
        }
 
        private void WpfMap_Loaded(object sender, RoutedEventArgs e)
        {
            wpfMap1.MapUnit = GeographyUnit.DecimalDegree;
            wpfMap1.CurrentExtent = new RectangleShape(-155.733, 95.60, 104.42, -81.9);
 
            WorldMapKitWmsWpfOverlay worldOverlay = new WorldMapKitWmsWpfOverlay();
            wpfMap1.Overlays.Add("WMK", worldOverlay);
 
            wpfMap1.MapClick += new EventHandler<mapclickwpfmapeventargs>(wpfMap1_MapClick);</mapclickwpfmapeventargs>
 
            wpfMap1.Refresh();
        }
 
 
        private void wpfMap1_MapClick(object sender, MapClickWpfMapEventArgs e)
        {
             if (e.MouseButton != MapMouseButton.Right)
             return;        
 
            ContextMenu cm = new ContextMenu();
 
            MenuItem mi = new MenuItem();
            mi.Header = (++ rightClickCount).ToString();
 
            cm.Items.Add( mi );
 
            wpfMap1.ContextMenu = cm;
        }
 
    }

 




Hi Keith,



To implement your requirement, we would like to recommend write code like this:

private int rightClickCount = 0;
private ContextMenu cm;

public DisplayASimpleMap()
{
    InitializeComponent();

    cm = new ContextMenu();
    Map1.ContextMenu = cm;
}

private void WpfMap_Loaded(object sender, RoutedEventArgs e)
{
    Map1.MapUnit = GeographyUnit.DecimalDegree;
    Map1.CurrentExtent = new RectangleShape(-155.733, 95.60, 104.42, -81.9);

    WorldMapKitWmsWpfOverlay worldOverlay = new WorldMapKitWmsWpfOverlay();
    Map1.Overlays.Add("WMK", worldOverlay);

    Map1.ContextMenu = cm;
    Map1.ContextMenuOpening += new ContextMenuEventHandler(Map1_ContextMenuOpening);
}

private void Map1_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    cm.Items.Clear();

    MenuItem mi = new MenuItem();
    mi.Header = (++rightClickCount).ToString();
    cm.Items.Add(mi);
}



Just feel free to let me know if you have more queries.



Thanks,

Howard



Keith, I had to do something similar so I have a controller class that creates context menus based on data type .  If you need more help on this, I can also chip in. 



Hi Klaus, 
  
 Thanks for your sharing.  
  
 Thanks, 
 Howard

Hello,



I have exactly the same Problem as the thread starter.

 Behaviour:

1. Right Click: Context Menu appears correctly on my mouse pointer on the Feature I clicked.

2. Right Click on different Feature: Context Menu stays on Position 1. Right Click but the text in the Menu Item changes correctly.

3. Right Click on different feature: Sometimes the context menu jumps correctly to my mouse pointer, sometimes it just stays at Position 1 but every time the text changes correctly.



Information Header Text:

If the context menu jumps correctly to my pointer on 3. Right Click it appear with the old text from 2. Right Click but changes to the right text after about 1 sec.



Additional Information:

I use WPF with the MVVM pattern.

All my context menu code is in the XAML.

Only the Header text and the MenuItem command are in my ViewModel.

Here the code:


<uc1:WpfMap.ContextMenu>
                    <ContextMenu Visibility="{Binding Path=FeatureContextMenuVisibility, Converter={StaticResource       ResourceKey=VisCon}}">
                        <MenuItem Command="{Binding Path=ContextMenuCommand}"
                            <MenuItem.Icon>
                                <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
                                       Style="{DynamicResource ResourceKey=ModulsContextMenuViewImageStyle}" />
                            MenuItem.Icon>

                            <MenuItem.Header>
                                <TextBlock Text="{Binding Path=ContextMenuHeader}" />
                            MenuItem.Header>

                        MenuItem>                      

                    ContextMenu>

                uc1:WpfMap.ContextMenu>



I hope you can give me an different solution for this Problem. I can not just delete my Menu Item and add it again because it is somewhat hardcoded in my XAML, but the behaviour of the contextMenu is definitly wrong. 



Edit:

I managed to solve the Problem with the Header text by collapsing the contextmenu in the MouseRightButtonUp Event of the WpfMap. Then I Change the Header text directly with map.ContextMenu.Header.Text = "myText". After that I set the visibility of the contextmenu to visible. Now it does not Show me the old text anymore for 1 second before changing.



The Problem with the contextmenu positioning still remains. Sometimes the contextmenu opens at my mouse Position and after another rightclick it does not repositioning the contextmenu but stays at the old Position.



Regards 

Daniel





Hi Daniel, 
  
 Thanks for your detail description. 
  
 I tested your code in our HowDoISample, only remove the Visibility(because I don’t have the static resource here), it looks context menu works well. 
  
 I am not sure whether I get correct way to reproduce that. 
  
 Could you please help me to reproduce that in our DisplayASimpleMap sample? 
  
 Regards, 
  
 Don 


Hello Don,



Thanks for your answer.



I resolved the Problem after a Long testing Phase myself.



Here is my solution:




<uc1:WpfMap.ContextMenu>
                    <ContextMenu>
                        <MenuItem Command="{Binding Path=ContextMenuCommand}">
                            <MenuItem.Icon>
                                <Image RenderOptions.BitmapScalingMode="NearestNeighbor"
                                       Style="{DynamicResource ResourceKey=ContextMenuViewImageStyle}" />
                            </MenuItem.Icon>
                        </MenuItem>
                    </ContextMenu>
</uc1:WpfMap.ContextMenu>

Then everytime I rightclick on the map I do the following:




map.MouseRightButtonUp += this.map_MouseRightButtonUp;
 
private void map_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
   var map = sender as WpfMap;
 
   map.ContextMenu.IsOpen = false;
 
   map.ContextMenu.Visibility = Visibility.Collapsed;
}

Then I have additionally a binding from my map to my viewmodel:



<i:Interaction.Behaviors> 


<
tg:WpfMapExtensions ItemsSource="{BindingPath=MapOverlays}"                                                                                                  
MapClicked="{Binding Path=MapClicked, Mode=TwoWay}"/>

</i:Interaction.Behaviors> 


And in my viewmodel I Switch to my MapExtension and there I do the following:


var newMenuItem = new MenuItem();
                    newMenuItem.Header = new TextBlock();
                    ((TextBlock)newMenuItem.Header).Text = "MyText"
                    var oldMenuItems = map.ContextMenu.Items.Cast<MenuItem>();
                    newMenuItem.Command = oldMenuItems.First().Command;
                    newMenuItem.Icon = oldMenuItems.First().Icon;
                    map.ContextMenu.Items.Clear();
                    map.ContextMenu.Items.Add(newMenuItem);
                    map.ContextMenu.Visibility = Visibility.Visible;



After adding the new MenuItem and Setting the visibility to visible the ContextMenu appears on my map with the right Header text and because i Change the isopen to false and to collapsed and the  back to visible it repositions on my mouse pointer. So the Problem is fixed. If anyone want more Details then let me know. Again: This is WPF with MVVM. And this solution is not perfect and is a not beautiful Workaround for the positioning Problem.



Regards 

Daniel

Hi Daniel,  
  
 I am glad to hear that solved and thanks very much for share your solution! 
  
 I think that’s should very helpful for other guys who met the same problem. 
  
 Any question please let us know. 
  
 Regards, 
  
 Don