How to Create a Table of Content

Hello Colleagues,

Does anybody develop a Table of Content to show all the layers with legend that we can turn on/off and change symbology? Do you use listedCheckBox inside Treeview? Would anyone share some code?

Thanks!
Lang

You could have a look at the demo tool we shipped with v4.9.6:

I’m not sure if it still works with MapWinGIS v5, but you can see some code.

You can also consider writting a plug-in for MW5 instead, then you can use the legend control of MW5.

I used datagridview in C# in detail view with checkboxes to show layer name, symbol, and turning on and off layer visibility. It can also use drag and drop to rearrange order of layers.

Its available at my github page.

You can also view the table of contents form code here

Dear RaffyM,

Thank you! I cloned your FAD solution and tried to open it in VS2019, but with many issues. Like
*FadUpdaterAug2019\FadUpdaterAug2019.vdproj: missing, build failed. Actually, I just like to see your mapping sections. Would you give me some instructions about how to open it and run it?
Thanks a lot!
lang

Continuing the discussion from How to Create a Table of Content:

Hello Lang,

I hope you were able to find a way to create a TOC. In my implementation, the TOC is represented by a form with a DataGridView containing 3 columns. The first column will contain a checkbox for layer visibility, the 2nd column will hold the layer name, and the 3rd column the layer’s symbol.

Regarding your problem in cloning the Solution, I think what you should do is to download just the source code files. The updaters that your are having a problem with are C# installer projects for updating or patching FAD that ia already installed in computers.

The form class that you are interested in is named MapLayersForm and can be found in the Mapping/Forms folder.

Constructor

Let’s take a look at the constructor:

    public MapLayersForm(MapLayersHandler mapLayers, MapperForm parent)
    {
        InitializeComponent();
        _parentForm = parent;
        _mapLayersHandler = mapLayers;
        _mapLayersHandler.LayerRead += OnLayerRead;
        _mapLayersHandler.LayerRemoved += OnLayerDeleted;
        _mapLayersHandler.OnLayerNameUpdate += OnLayerNameUpdated;
        _mapLayersHandler.LayerRefreshNeeded += OnLayerRefreshRequest;
        layerGrid.CellClick += OnCellClick;
        layerGrid.CellMouseDown += OnCellMouseDown;
        layerGrid.CellDoubleClick += OnCellDoubleClick;
        layerGrid.DragDrop += OnLayerGrid_DragDrop;
        layerGrid.DragOver += OnLayerGrid_DragOver;
        layerGrid.MouseDown += OnLayerGrid_MouseDown;
        layerGrid.MouseMove += OnLayerGrid_MouseMove;
    }

I am implementing DragDrop and DragOver on the rowns of the DataGridView. This will be used to rearrange order of the layer.

Adding a layer to the form

LayerRead is an event that happens whenever a Layer is loaded into the form.

    private void OnLayerRead(MapLayersHandler mapLayersHandler, LayerEventArg e)
    {
        if (e.ShowInLayerUI)
        {
            //set the layer preview thumbnail
            PictureBox pic = new PictureBox
            {
                Height = layerGrid.RowTemplate.Height,
                Width = layerGrid.Columns[2].Width,
                Visible = false
            };
            _mapLayersHandler.LayerSymbol(e.LayerHandle, pic, e.LayerType);

            if (!_mapLayersHandler[e.LayerHandle].IsMaskLayer)
            {
                layerGrid.Invoke((MethodInvoker)delegate
                {
                    //we always insert a new layer in the first row of the dataGrid
                    layerGrid.Rows.Insert(0, new object[] { e.LayerVisible, e.LayerName, pic.Image });

                    //we assign the layerhandle to the tag of cell 0,0
                    layerGrid[0, 0].Tag = e.LayerHandle;

                    //symbolize the current layer by making it bold font
                    MarkCurrentLayerName(CurrentLayerRow());
                });
            }
        }
    }

How the layer’s symbology is created

I use a PictureBox to show layer symbology and I pass it as a parameter to a MapLayersHandler.LayerSymbol method.

The LayerSymbol method takes in a layer handle and a picture box. It examines what kind of layer is being passed. If it is a ShapeFile, it uses ShapeDrawingOptions to copy the symbology of the layer to the picture box. If the layer is of type Image, it copies a thumbnail of the image into the picturebox.

Finally, adding a row to the DataGridView representing a map layer

Back to MapLayersForm, the newly added layer is inserted to first row of the DataGridView:

layerGrid.Rows.Insert(0, new object[] { e.LayerVisible, e.LayerName, pic.Image });


The syntax of adding a new row to a DataGridView takes in an array representing the columns.

new object[] { e.LayerVisible, e.LayerName, pic.Image }'

e.LayerVisible determines the checked state of the checkbox of the first column and this turns on or off the layer’s visbility.

The second element is e.LayerName and this will add the layer name to the 2nd columns

The third element is pic.Image and this will add the symbol of the layer.

1 Like

Hi RaffyM,

First thank you so much for the very insightful guidance! Very appreciated!
Your instructions are very helpful to me. I am now just using a TreeView as TOC, which has many limitations. I’ll try your idea to use a form with DataGridView.
Thank you again! Sorry for the delayed response, I thought you may not check in here any more.
lang

@Lang I posted on GitHub a mapping project that contains just the the mapping functionality of FAD.

Taking a look at my references, you can see that you need to reference Microsoft.VisualBasic.PowerPacks because it is required when viewing/editing the symbology of shapefiles
reference list

EDIT: Use MapWinGIS version 4.9.6.1 because it is the version that I am sure all functionality will work.

@RaffyM Can you post (in another thread) the issues your facing with the latest version of MapWinGIS?
I always encourage people to upgrade and if it is not possible for their workflow we want to help and make it work. MapWinGIS v4.9.6 is very old.

@RaffyM Thank you so much! I cloned your mapping project and is trying to run it. But I am now stuck by the Owf.Controls.Office2007ColorPicker.dll. It is no where to be found. Will you give me a link? May I use WPF ColorPicker Like Office 2007 instead? I see you use this dll a lot in your code.
Thank you again!

Hello @lang

There is a project named Owf.Controls.Office2007ColorPicker in the solution that you downloaded/cloned. It contains the source code for the dll. Just build it. Then in the debug folder, you will see Office2007ColorPickerdll. Add it as a reference to the MapWinForms project.

I also updated the readme for the project regarding the colorpicker dll

@RaffyM Appreciate the very quick response and instruction a lot! I did it and got the dll and added it to references. Now I get this in PolygonLineLayerSymbologyForm.designer.cs:

this.clpHatchBack = new Owf.Controls.Office2007ColorPicker(this.components);

|Error|CS1061|‘PolygonLineLayerSymbologyForm’ does not contain a definition for ‘clpHatchBack’ and no accessible extension method ‘clpHatchBack’ accepting a first argument of type ‘PolygonLineLayerSymbologyForm’ could be found (are you missing a using directive or an assembly reference?) |MapWinForms|C:\Users\ldeng\source\repos\MapWinForms\forms\PolygonLineLayerSymbologyForm.designer.cs|48|Active|

Any idea?
Thanks!

clpHatchBack is just a color picker derived from the colorpicker dll. It is used to provide the background color for hatch fills. Maybe it got removed from the form designer when it couldn’t find a reference to Office2007ColorPicker.dll

First make sure that the Office2007ColorPicker control is available in the toolbox.

Have you downloaded the demo project created by MapWinGIS? This is where I got all the code I used for creating the symbology form and I copied a lot from it.

Thank you Raffy!

I checked, the Office2007ColorPicker is not available as a control in toolbox.
I wonder if I miss one step? I added Owf.Controls.Office2007ColorPicker to the reference. Do we need to do something more to make it work?

Regards,
lang

try registering it (the color picker dll) by using regsvr32

Dear Raffy,
Tried in system32 and syswow64 to register the dll, all failed. Maybe it doesn’t contain a DLLRegisterServer?
Thank you!

Have you tried searching for the item in the toolbox? For example, if you type “office”, the office2007color picker should come up as a result.

Raffy, I did. Not found. Hard to believe this small issue can stop everything.

Lang, if you cannot load the color picker dll, maybe you can just adopt the code to choose colors in the PointLayerSymbology form. I did not use a color picker, instead you just dbl-click on a shape to select colors from a standard color dialog.

Hi Raffy,
Thanks a lot! I’'ll try that. Sorry for the delayed response.
lang