This is a migrated thread and some comments may be shown as answers.

Bind MapShapeData fill color

6 Answers 167 Views
Map
This is a migrated thread and some comments may be shown as answers.
Etienne
Top achievements
Rank 1
Etienne asked on 30 Jul 2015, 09:30 PM

Hi,

Is there a way to bind the fill color of a map shape to a property of my DataContext but I can't do it. Here's what I've tried:

<DataTemplate x:Key="FooTemplate" DataType="Foo">
    <telerik:MapPathView>
        <telerik:MapPathView.Data>
            <tmpl:FooView .../>
        </telerik:MapPathView.Data>
        <telerik:MapPathView.ShapeFill>
            <telerik:MapShapeFill Fill="{Binding SomeProperty, Converter={StaticResource SomePropertyToBrushConverter}}" StrokeThickness="1"/>
        </telerik:MapPathView.ShapeFill>
    </telerik:MapPathView>
</DataTemplate>

When I run, I have an error "Cannot find source for binding with reference ..." because MapSahpeFill doesn't inherit the "inheritance context".

So is there a way to achieve what I want ?

Thank you,

Etienne

6 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 04 Aug 2015, 11:30 AM
Hello Etienne,

I am afraid that since the MapPathView element it is not presented in the visual tree and it doesn't inherit the data context for its content presenter, the Stroke property of the MapShapeFill cannot be bound. In order to achieve your requirement you can define a MapShapeFill property in your view model and try to bind it to the ShapeFill property of the MapPathView.
<telerik:MapPathView ShapeFill="{Binding FlightPathFillDescription}">
You can also consider using a FrameworkElement directly instead of the map's bindable wrappers. For example:
<Path Fill="{Binding SomeProperty, Converter={StaticResource SomePropertyToBrushConverter}"
      telerik:MapLayer.Location="{Binding Location}">
    <Path.Data>
        <!-- define the path data -->
    </Path.Data>   
</telerik:MapPathView>
Using this approach the you will need to recalculate the path's data each time the zoom level is changed since it it define in pixels. You can convert Point to Location you can use the Location.GetCoordinates() static method.

I hope this information helps.

Regards,
Martin
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Etienne
Top achievements
Rank 1
answered on 04 Aug 2015, 05:27 PM

Hi Martin,

Thank you for your answer, I've tried the first solution (ShapeFill bound to a property in the view model) but it doesn't work well. The ShapeFill is not updated immediately when the property in my view model is updated. I must zoom a lot and move the map to see the change of the fill color being applied.

Also, do you have an example for the second solution, I'm not sure how to do that.

Thank you,

Etienne

0
Accepted
Martin Ivanov
Telerik team
answered on 07 Aug 2015, 11:45 AM
Hi Etienne,

In order for the ShapeFill to be updated properly you will need to write some custom code. Basically, you can use an attached property and in its OnPropertyChangedCallback method you can set the shape fill to the wrapper. Then call the UseRegularFill() method of the wrapper's ShapeData. Here is an example:
public class MapUtilities
{
    public static MapShapeFill GetShapeFill(DependencyObject obj)
    {
        return (MapShapeFill)obj.GetValue(ShapeFillProperty);
    }
 
    public static void SetShapeFill(DependencyObject obj, MapShapeFill value)
    {
        obj.SetValue(ShapeFillProperty, value);
    }
 
    public static readonly DependencyProperty ShapeFillProperty =
        DependencyProperty.RegisterAttached("ShapeFill", typeof(MapShapeFill), typeof(MapUtilities), new PropertyMetadata(null, OnShapeFillChanged));
 
    private static void OnShapeFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {  
        var wrapper = (MapShapeBindableWrapper)d;
        if (e.NewValue != null)
        {
            wrapper.ShapeFill = (MapShapeFill)e.NewValue;
            var shapeData = wrapper.ShapeData;
            shapeData.UseRegularFill();
        }          
    }
}

<DataTemplate x:Key="FooTemplate" DataType="Foo" local:MapUtilities.ShapeFill="{Binding FlightPathFillDescription}">
    <telerik:MapPathView>
        <telerik:MapPathView.Data>
            <tmpl:FooView .../>
        </telerik:MapPathView.Data>
    </telerik:MapPathView>
</DataTemplate>
I also attached a sample project demonstrating this approach. Please give it a try and let me know if it works for you.

As for the second solution, currently I do not have an example with this approach.

Regards,
Martin
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Etienne
Top achievements
Rank 1
answered on 07 Aug 2015, 07:36 PM

Hi Martin,

Thank you for the solution, it works great! I don't know why it haven't been done this way in the first time, but think it would be nice if the ShapeFill property of MapShapeBindableWrapper had the same behavior then the one you made in MapUtilities.

Thanks again!

Etienne

0
Luke
Top achievements
Rank 1
answered on 04 Apr 2016, 08:21 AM
Good Morning Petar

This perhaps is getting complicated for my simple needs.  All I want to do is change the colour of a given country

How I was doing previously with the Information layer was looping through all the shape names until the one I wanted was found, then adjusting its fill colour inside the loop.

To reset all the colours, I did the same, but without singling out a particular country, and adjusting all of their fill colours.

I would be quite happy to do the same, but its accessing each country that is the problem (and why I changed direction and thought I could bind a colour from the model).

Is there any simple solution for changing country colours in the back end with a visulization layer driver by SQL shape data – I image the countries exist somehow as an individual entity as they are an individually selectable.

Thanks
0
Petar Mladenov
Telerik team
answered on 05 Apr 2016, 07:17 AM
Hello,

I have modified our ManualShapeReading SDK sample in the following way:
                -- Informationlayer is replaced with VisualizationLayer
                -- ShapeReader is replaced with AsyncShapeFileReader
                --When read is complete - all shape objects's indices are stored a dictionary in format <countryName, index>
                -- On a Button Click the Russia's shape ShapeFill is changed runtime. Please note here that if you change the ShapeFill, HighlightFill or SelectedFill properties then you need to use UseRegularFill / UseHighlightFill / Use SelectedFill methods. These 3 methods change the ActualShapeFill internal property which is bound in the template of the shapes.

We hope the solution will help you move forward.


Regards,
Petar Mladenov
Telerik
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
Map
Asked by
Etienne
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Etienne
Top achievements
Rank 1
Luke
Top achievements
Rank 1
Petar Mladenov
Telerik team
Share this question
or