problem with ShowDialog()

Jan 27, 2014 at 11:26 AM
Edited Jan 27, 2014 at 12:09 PM
Hello !

I use the last version of mapwingis dll (4.8) and active x control to develop an application in C#.
I need to display winForm when the user click on the map. So, I catch the event "AxMap_MouseDownEvent", I instanciate a state (design pattern state) and I display a messageBox or a personalized form with the method "ShowDialog()" to force the user to give informations.
I have a big problem with this. Sometimes, display a form with "ShowDialog()" causes problem with the map (like this old posts : http://www.mapwindow.org/phorum/read.php?3,16731,16824#msg-16824 ; http://www.mapwindow.org/phorum/read.php?3,18257,18339#msg-18339 ).
More specifically, if I try to move the map with pan, the map returns to its original extent and if I resize the window, the map become Black (big rectangle in black).
When I replace "ShowDialog()" by "Show()" (for personalized form), there is no problem but I need stop the thread to force the user to complete these forms.
I think there is a problem with the fact that stop thread in an event of mapwingis (this is the effect of "ShowDialog()"). This looks suspiciously like a refresh problem but I tried all refresh(), redraw(), focus() and more... Moreover, when there is the problem, if I do Alt/Tab to focus on another window and Alt/Tab again to come back on my application, active X control work again and the same things happens if I double click on the map.
The only things I don't understand is why this problem don't occurs always (not in all states but always in the same states). I tried to debug my code during one day to see if there was differences between code but there are none.

Thanks for your help, I'm desperate after one day of debugging.

Tristan
Jan 27, 2014 at 12:26 PM
I tried the following and it behaves correctly. Are you trying to do something different from this?
public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        axMap1.MouseDownEvent +=new AxMapWinGIS._DMapEvents_MouseDownEventHandler(axMap1_MouseDownEvent);
    }

    void axMap1_MouseDownEvent(object sender, AxMapWinGIS._DMapEvents_MouseDownEvent e) {
        Form2 form2 = new Form2();
        form2.ShowDialog();
    }
}
Don
Jan 27, 2014 at 12:51 PM
Edited Jan 27, 2014 at 12:53 PM
No, I do like you. The only difference is that in the "axMap1_MouseDownEvent" function I have :
        private void AxMap_MouseDownEvent(object sender, AxMapWinGIS._DMapEvents_MouseDownEvent e)
        {
            bool endState = false;
            if (e.button == 1)
            {
                _clickButton = 1;
                endState = _currentState.MouseLeftDown(e.x, e.y);
            }

            if (e.button == 2)
            {
                _clickButton = 2;
                endState = _currentState.MouseRightDown();
            }

            if (endState == true)
            {
                _currentState = new StateNeutral(_axMap);
            }
        }
cause I use desing pattern state. But, for example when I draw a polygon I display two messageBox and it works without problem (here the code in the state drawArea) :
public override bool MouseRightDblClick()
        {
            //Il faut au minimum trois points pour créer un polygone
            if (_numberOfPoint >= 3)
            {
                CreateAreaOfInterest popupCreateAreaOfInterest = new CreateAreaOfInterest();

                while (__DialogResult.OK == popupCreateAreaOfInterest.ShowDialog()__)
                {

                    if (_manager.CheckIfIntelligenceFeatureCanBeCreated(popupCreateAreaOfInterest.GetName().ToLower(), MainManager.TypeOfFeatureIntelligence.areaOfInterest) == true)
                    {

                        //Création du shape représentant la zone
                        Shape newAreaOfInterest = new Shape();
                        newAreaOfInterest.Create(ShpfileType.SHP_POLYGON);
                        int i;
                        for (i = 0; i < _numberOfPoint; i++)
                        {
                            Point newPoint = new Point();
                            newPoint.x = _listOfPoints[i].Longitude;
                            newPoint.y = _listOfPoints[i].Latitude;
                            newPoint.Z = _listOfPoints[i].Altitude;
                            newAreaOfInterest.InsertPoint(newPoint, ref i);
                        }
                        i++;
                        MapWinGIS.Point firstPoint = new MapWinGIS.Point();
                        firstPoint.x = _listOfPoints[0].Longitude;
                        firstPoint.y = _listOfPoints[0].Latitude;
                        firstPoint.Z = _listOfPoints[0].Altitude;
                        newAreaOfInterest.InsertPoint(firstPoint, ref i);

                        //Ajout du shape dans le shapefile
                        int handlerLayerOfAreaOfInterest = _manager.GetHandleStaticLayer(MainManager.TypeOfFeatureIntelligence.areaOfInterest);
                        Shapefile layerOfAreaOfInterest = _axMap.get_Shapefile(handlerLayerOfAreaOfInterest);
                        int indexOfNewAreaOfInterest = layerOfAreaOfInterest.NumShapes;
                        layerOfAreaOfInterest.EditInsertShape(newAreaOfInterest, ref indexOfNewAreaOfInterest);

                        //Changement des propriétés d'affichage
                        ShapefileCategory cat = layerOfAreaOfInterest.Categories.Add("display" + popupCreateAreaOfInterest.GetName());
                        cat.DrawingOptions.FillColor = System.Convert.ToUInt32(System.Drawing.ColorTranslator.ToOle(popupCreateAreaOfInterest.GetColorBackground()));
                        cat.DrawingOptions.FillTransparency = popupCreateAreaOfInterest.GetOpacity();
                        cat.DrawingOptions.LineVisible = popupCreateAreaOfInterest.GetCheckStateBorder();
                        cat.DrawingOptions.LineColor = System.Convert.ToUInt32(System.Drawing.ColorTranslator.ToOle(popupCreateAreaOfInterest.GetColorBorder()));
                        cat.DrawingOptions.LineWidth = popupCreateAreaOfInterest.GetWitdhBorder();
                        layerOfAreaOfInterest.set_ShapeCategory(indexOfNewAreaOfInterest, layerOfAreaOfInterest.Categories.get_CategoryIndex(cat));

                        //Ajout de la nouvelle zone dans le manager
                        _listOfPoints.Add(new Point3D(_listOfPoints[0].Latitude, _listOfPoints[0].Longitude, _listOfPoints[0].Altitude, _listOfPoints[0].Name));
                        _manager.AddAreaOfInterestToList(_manager.CreateAreaOfInterest(_listOfPoints, popupCreateAreaOfInterest.GetName(), popupCreateAreaOfInterest.GetCheckStateFill(), popupCreateAreaOfInterest.GetColorBackground(), popupCreateAreaOfInterest.GetOpacity(), popupCreateAreaOfInterest.GetColorBorder(), popupCreateAreaOfInterest.GetWitdhBorder()), handlerLayerOfAreaOfInterest, indexOfNewAreaOfInterest, popupCreateAreaOfInterest.GetName());

                        __MessageBox.Show("Polygon created");__

                        _axMap.ClearDrawing(_handleDrawingLayer);
                        _listOfPoints.Clear();
                        _numberOfPoint = 0;
                        _lastPoint = new Point3D();
                        _mapLocked = false;     
        }
When I try to draw a point (in the state DrawPoint) with the code following, it doesn't works : the cursor of the map become the cursor of the whole application (I have a treeview and a propertyGrid), I can't move the map and If I resize, the map become black.
public override bool MouseLeftDown(int x, int y)
        {
            MessageBox.Show("Testing");
            //Ajout du shape dans le shapefile
            int handlerLayerOfPlatform = _manager.GetHandleStaticLayer(MainManager.TypeOfFeatureIntelligence.platform);
            Shapefile layerOfPlatform = _axMap.get_Shapefile(handlerLayerOfPlatform);
            int indexOfNewPlatform = layerOfPlatform.NumShapes;

            //Création du shape représentant la plafeforme
            Shape newPlatform = new Shape();
            newPlatform.Create(ShpfileType.SHP_POINT);
            Point newPoint = new Point();
            double longitudeOrX = 0.0;
            double latitudeOrY = 0.0;
            _axMap.PixelToProj(x, y, ref longitudeOrX, ref latitudeOrY);
            newPlatform.AddPoint(longitudeOrX, latitudeOrY);

            //Ajout du nouveau point dans la couche correspondante
            layerOfPlatform.EditInsertShape(newPlatform, ref indexOfNewPlatform);
            _axMap.Redraw();
        }
See this image to understand : http://www.hostingpics.net/viewer.php?id=484073Sanstitre.png
Jan 27, 2014 at 12:57 PM
Moreover, when the axMap bug, if I double click with the left button on the map, it works good again (the extents change and I don't see the map, I need to zoom in or zoom out to retrieve the map but its fine).
Jan 27, 2014 at 1:22 PM
Other information: when I debug, if I set a breakpoint after the messagebox, the map works fine. I feel that the map has not the time to refresh after the closure of the messageBox. But I already tried refresh(), redraw(), focus(), ect...
Jan 27, 2014 at 1:49 PM
Again, another informations.
I tried to do a little project to reproduce my problem.

CLASSE WITH THE FORM AXMAP :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace test
{
    public partial class Form1 : Form
    {
        StateDrawPlatform test;
        public Form1()
        {
            InitializeComponent();
            axMap1.SendMouseDown = true;
            test = new StateDrawPlatform(this.axMap1);
        }

        private void AxMap_MouseDownEvent(object sender, AxMapWinGIS._DMapEvents_MouseDownEvent e)
        {
            bool endState = false;
            if (e.button == 1)
            {
                MessageBox.Show("test");
                //test.MouseLeftDown(e.x, e.y);
            }
        }
    }
}
CLASSE STATEDRAWPOINT :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapWinGIS;
using System.Windows.Forms;

namespace test
{
    public class StateDrawPlatform
    {
        private AxMapWinGIS.AxMap _axMap;

        public StateDrawPlatform(AxMapWinGIS.AxMap newAxMap)
        {
            newAxMap.DisableWaitCursor = true;
            newAxMap.CursorMode = tkCursorMode.cmPan;
            newAxMap.MapCursor = tkCursor.crsrCross;
            newAxMap.Focus();
        }

        public void MouseLeftDown(int x, int y)
        {
            MessageBox.Show("test");
        }
    }
}
When I do that, I have one of the same problem than my application : the cursor in the window bar of the form is the same than the map.
Jan 27, 2014 at 3:18 PM
Don,

I have the confirmation its a bug of mapwingis. When I tried this very little code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace test2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            axMap1.SendMouseDown = true;
            axMap1.MouseDownEvent += new AxMapWinGIS._DMapEvents_MouseDownEventHandler(axMap1_MouseDownEvent);
        }

        private void axMap1_MouseDownEvent(object sender, AxMapWinGIS._DMapEvents_MouseDownEvent e)
        {
            axMap1.CursorMode = MapWinGIS.tkCursorMode.cmPan;
            MessageBox.Show("test2");
            axMap1.CursorMode = MapWinGIS.tkCursorMode.cmPan;
        }
    }
}
Launch this code : click on the map, messageBox appear and close it.
1) the cursorMode don't change (maybe change the cursormode in an event axmap its bad, in this case its my fault)
2) impossible to close the form with the red close button of the window : all application is blocked in the mode of the map

Tristan
Jan 27, 2014 at 3:42 PM
Hi Tristan,

Yes, I think it is bad to interrupt the mouse down event. Mouse down could be the first step of a zoom, pan, draw a selection box. So changing the cursor in the middle of that behavior is going to be problematic.

I don't know if this will help, but what I do is derive a mouse click by setting a "possibleMouseClick" flag on a mouse down then raise my own click event on a mouse up if the mouse hasn't moved in the interim. This has worked very well for me, and I've had no issues with cursors, redraws, or modes (select, pan, zoom, etc.).

Don
Jan 27, 2014 at 3:52 PM
Hi DonRahmlow,

Thanks for your help.

I don't understand all of your idea ;)

Can you give me a little example of code (just lines of your "flag") ?

Tristan
Jan 27, 2014 at 4:22 PM
Tristan--"possibleMouseClick" is the flag I was talking about. Someone else probably has a more elegant solution but this works great for me. --Don
    public static void Map_MouseDownEvent(object sender, _DMapEvents_MouseDownEvent e) {
        // Only process if in select mode
        if (mouseMode != MouseModes.Select) return;

        if (e.button == 2) {
            MouseDownRight(e.x, e.y);
        }
        else {
            possibleMouseClick = true;
        }
    }

    public static void Map_MouseUpEvent(object sender, _DMapEvents_MouseUpEvent e) {
        if (mouseMode != MouseModes.Select) return;

        if (possibleMouseClick) {//no movement since mouse down is a click
            MouseClick();
            possibleMouseClick = false;
        }
    }

    public static void Map_MouseMoveEvent(object sender, _DMapEvents_MouseMoveEvent e) {
        // Moving mouse cancels possible click
        if (e.button == 0) { //no button means can't be dragging
            IsDragging = false;
        }
        if (mouseMode != MouseModes.Pan && !IsDragging) {  //mouse ignored if in pan or dragging (i.e., selection box) mode
            previousMousePositionX = e.x;
            previousMousePositionY = e.y;
            possibleMouseClick = false;
            AppController.NotifyMouseOrGpsPositionUpdate(Globals.Globals.PositionUpdateEventSource.Mouse, e.x, e.y);
        }
    }
Jan 28, 2014 at 7:02 AM
DonRahmlow,

Thanks for your idea. You're right, stop the axmap_mouseDownEvent occurs lots of problem. With your solution (I personalized your code for my purposes) its good. So, the solution is to do the computing and processing in the Axmap_MouseUpEvent.

Thanks for you help and your patience.

Tristan