ThinkGeo.com    |     Documentation    |     Premium Support

Correct way to change text style color, size, etc

I’d like to modify an existing layer’s custom text style to use a different color or font. We’re initializing the layer with some custom text styles and then we’d like to modify them as needed. I’ve tried modifying the existing custom text style’s color like this (s is the TextStyle):

s.TextSolidBrush.Color = new GeoColor(aclrOrigFonts[1].AlphaComponent, aclrRes[0].RedComponent, aclrRes[0].GreenComponent, aclrRes[0].BlueComponent);

I’ve also tried looping through the CustomStyles of each ZoomLevel, removing the TextStyles that need to be replaced, creating new TextStyles with the new colors and fonts and then adding the new TextStyles to the CustomStyles.

Both approaches work on occasion but mostly tend to result in a crash down in the ThinkGeo code somewhere. I haven’t been able to trace it back to a spot in our code. I’m curious as to whether modifying a TextStyle like this is possible or not and if so, what the best way is to do it… If not, we can just recreate the layers from scratch with the new color and font.

Tnanks,
Neil

Hi Neil,

I build a really simple sample with our latest development dlls, it looks everything goes well, please have a try it and see whether that works for you.

using System;
using System.Windows;
using System.Windows.Controls;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WpfDesktopEdition;

namespace CSHowDoISamples
{
    public partial class DisplayASimpleMap : UserControl
    {
        public DisplayASimpleMap()
        {
            InitializeComponent();
        }

        private void WpfMap_Loaded(object sender, RoutedEventArgs e)
        {
            InMemoryFeatureLayer layer = new InMemoryFeatureLayer();

            Feature testFeature = new Feature(0, 0);
            testFeature.ColumnValues.Add("label", "It's a label for test!");

            layer.InternalFeatures.Add(testFeature);

            TextStyle customTextStyle = new TextStyle();
            customTextStyle.TextColumnName = "label";
            customTextStyle.Font = new GeoFont("Arial", 20, DrawingFontStyles.Bold);
            customTextStyle.TextSolidBrush.Color = GetRandomColor();

            layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(PointStyles.Capital1);
            layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(customTextStyle);
            layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay overlay = new LayerOverlay();
            overlay.Layers.Add(layer);

            Map1.Overlays.Add("TestOverlay", overlay);

            Map1.MapUnit = GeographyUnit.DecimalDegree;
            Map1.CurrentExtent = new RectangleShape(-10, 10, 10, -10);

            Map1.Refresh();
        }

        private GeoColor GetRandomColor()
        {
            Random random = new Random();
            int a = random.Next(200, 255);
            int r = random.Next(0, 255);
            int g = random.Next(0, 255);
            int b = random.Next(0, 255);

            return new GeoColor(a, r, g, b);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TextStyle customTextStyle = new TextStyle();
            customTextStyle.TextColumnName = "label";
            customTextStyle.Font = new GeoFont("Arial", 20, DrawingFontStyles.Bold);
            customTextStyle.TextSolidBrush.Color = GetRandomColor();

            ((Map1.Overlays["TestOverlay"] as LayerOverlay).Layers[0] as InMemoryFeatureLayer).ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
            ((Map1.Overlays["TestOverlay"] as LayerOverlay).Layers[0] as InMemoryFeatureLayer).ZoomLevelSet.ZoomLevel01.CustomStyles.Add(customTextStyle);
            ((Map1.Overlays["TestOverlay"] as LayerOverlay).Layers[0] as InMemoryFeatureLayer).ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            Map1.Refresh();
        }
    }
}

Wish that’s helpful.

Regards,

Don

That works just fine for me as well. It looks like the problem is somewhere else in our application. Thanks for the help. At least now I know it’s us and not ThinkGeo :slight_smile: I’ll check into some other areas of our project.

Hi Neil,

I am glad to hear that’s helpful for you.

Regards,

Don

I’m still experiencing stability issues that I believe are due to our mishandling of the map with regards to threading. Our application is connecting to a message queue (MSMQ) and receiving data from a C++ application. The queue works fine and the ThinkGeo application is using event notification to receive queue messages asynchronously. We’re modifying the map layers’ text, line, and area styles depending on the type of message received. After a few messages we get this in an unhandled exception:

The Layer must be opened before you can perform this method.

I’ve also seen messages referencing a collection that was modified and cannot be enumerated. The exception appears to come from ThinkGeo and doesn’t trace back to our code. I’ve tried locking the map’s feature layers as we work on them but that doesn’t appear to help. What’s the proper way to handle this kind of thing? I’ve experimented with performing the updates through a simple button press from the main gui and that has worked fine, so I’m fairly certain there’s a threading issue that I’m missing.

Let me know if you need more clarity as this is a little hard to explain. My C# knowledge is a work in progress.

Hi Neil,

It looks a little complex for your scenario, if that’s hard to reproduce and find the reason, I suggest you open all the layers when they are using in map and close them if you make sure they will be disposed and won’t be used by map again, which should avoid met this exception again.

If the exception still happen after you open all layers, please provide us a sample project for reproduce that. Wish that’s helpful.

Regards,

Don

Thanks for the suggestion. That seems to have done the job. We’ll keep an eye on it, but for now I think we’re good.

Hi @Neil4,

I am glad to hear that’s helpful, any question please let me know.

Regards,

Don

MapSuite Team,

I continue to have this same exact issue. I’ve tried changing my code any number of ways, but to no avail. I’m convinced this is a threading/timing issue within MapSuite. Each of our workstations will encounter these several times a day. Sometimes the application has to be stopped/started as it is no longer functioning properly.

Attached is a text file which shows a few of these.

This happens on ShapeFileFeatureLayer, SQLiteFeatureLayer, and InMemoryFeatureLayer.

The application opens all layers at startup and never closes them. The LayerOverlay LockLayerMode Property is set to Lock.

I am using WpfDesktopEdition 9.0.0.190.

Regards,
Dennis

CollectionWasModified20160423.txt (1.6 KB)

Hi Dennis,

Thanks for reporting this issue, I reproduced the exceptions.
We will look into problem and see how to solve it, our developers are working on it, any updates I will let you know.

Thanks,
Emil

Hi Dennis,

I did some tests, and found the cause of this issue on my side.
The application draws the tiles asynchronously. in the process of drawing, the style has been modified, so the exception has occurred.

There are two options you can have a try:

1. Please set the TileType property in LayerOverlay to "SingleTile".
2. Please set the LockLayerMode in LayerOverlay to "DoNotLock".

Also, there is one thing we need to confirm:
Is the scene of your application consistent with the code Don mentioned earlier? It means that something(such as styles) will be changed frequently in the process of running.

If any misunderstood, could you please provide more information, or a simple sample that duplicates the problem on a consistent basis?

Thanks,
Emil