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

ClusteredDataSource Binding

2 Answers 108 Views
Map
This is a migrated thread and some comments may be shown as answers.
Mehmet
Top achievements
Rank 1
Mehmet asked on 16 Jul 2012, 12:40 PM
Hi,
I'm developing an application that users can drag and drop items on a  radmap and move them around. I wanted to use ClusteredDataSource for drill down ability, but i'm struggling on binding the location property of my custom class.

here is my custom object:
    public class ToolboxItem : ContentControl
    {
        public String IconPath { get; set; }

        public String Description { get; set; }

        public Location Location { get; set; }

    }

And my ObservableCollection :

    public class ItemsDataSource : ObservableCollection<ToolboxItem>
    {
        Random rnd = new Random();

        public ItemsDataSource()
        {
            this.GeoBoundsNW = new Location(39, -120);
            this.GeoBoundsSE = new Location(32, -113);
            CreatePointsInRect(100);
        }

        private LocationRect dataRectangle = new LocationRect();
        public LocationRect DataRectangle
        {
            get { return dataRectangle; }
            set
            {
                dataRectangle = value;
            }
        }

        private Location geoBoundsNW = Location.Empty;
        public Location GeoBoundsNW
        {
            get { return geoBoundsNW; }
            set
            {
                geoBoundsNW = value;
                UpdateGeoBounds();
            }
        }

        private Location geoBoundsSE = Location.Empty;
        public Location GeoBoundsSE
        {
            get { return geoBoundsSE; }
            set
            {
                geoBoundsSE = value;
                UpdateGeoBounds();
            }
        }

        private void UpdateGeoBounds()
        {
            if (!this.GeoBoundsNW.IsEmpty && !this.GeoBoundsSE.IsEmpty)
            {
                this.DataRectangle = new LocationRect(this.GeoBoundsNW, this.GeoBoundsSE);
            }
        }

        #region Test
        private void CreatePointsInRect(int count)
        {
            if (!this.dataRectangle.IsEmpty)
            {
                for (int i = 0; i < count; i++)
                {
                    ToolboxItem item = new ToolboxItem();
                    Location loc = new Location(
                        this.DataRectangle.North - this.DataRectangle.GeoSize.Height * rnd.NextDouble(),
                        this.DataRectangle.West + this.DataRectangle.GeoSize.Width * rnd.NextDouble());
                    item.Name = "item" + i;
                    item.Location = loc;
                    
                    this.Add(item);
                }
            }
        }
        #endregion

    }

and my clustered data source defiifnition in xaml file:

                    <local:ItemsDataSource x:Key="ItemsDataSource" />

                    <telerik:ClusteredDataSource x:Key="clusteredDataSource"
                                                 ClusterItemTemplate="{StaticResource ClusterTemplate}"
                                                 ItemTemplate="{StaticResource ClusteredItemTemplate}"
                                                 GenerateClustersOnZoom="True"
                                                 ItemsSource="{StaticResource ItemsDataSource}">

                    </telerik:ClusteredDataSource>

and of course my rad map control:

        <telerik:RadMap Name="radMap"
                        AllowDrop="True"
                        Grid.Column="2"
                        Grid.Row="1"
                        ZoomBarVisibility="Collapsed"
                        ZoomLevel="4"
                        Center="39,-120">
            <telerik:RadMap.Provider>
                <telerik:OpenStreetMapProvider />
            </telerik:RadMap.Provider>
            <telerik:InformationLayer x:Name="infLayer" AllowDrop="True"
                                      ClusteredDataSource="{StaticResource clusteredDataSource}">
            </telerik:InformationLayer>
        </telerik:RadMap>

and Clustered Item Template :
                    <DataTemplate x:Key="ClusteredItemTemplate">
                        <telerik:MapPinPoint telerik:MapLayer.Location= "{Binding Converter={StaticResource locConverter}}"
                                             MouseLeftButtonUp="ClusteredItemMouseClick"/>
                    </DataTemplate>

On data template i tried to bind Location property of my ToolboxItem but it was an unsuccessful attempt so then i provided an IValueConverter which is just below.

    public class LocationConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var item = value as ClusteredItem;
            var toolboxItem = item.Data as ToolboxItem;

            return toolboxItem.Location;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

    }


The problem is if i change type of the ObservableCollection to Location it works perfectly, but i need to provide additional information for the visual and also for the status of the item. So i have to use my ToolboxItem as a type on my ObservableCollection, but i couldn't bind the Location property from toolboxItem.

Does anybody have any idea how to do that.

Thanks,

2 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 19 Jul 2012, 07:44 AM
Hi Mehmet,

The MapLayer.Location property in the clustered item template (ClusteredItemTemplate) should always be bound to the "Location" property of the ClusteredItem. In your data template it is bound to the "Location" property of the original data. I.e. the data template should look like this:

<DataTemplate x:Key="ClusteredItemTemplate">
    <telerik:MapPinPoint telerik:MapLayer.Location="{Binding Path=Location}"
             Text="{Binding Path=Data.Text}"
             ImageSource="{Binding Path=Data.ImageSource}"
             MouseLeftButtonUp="ClusteredItemMouseClick">
        <telerik:MapPinPoint.Background>
            <SolidColorBrush Color="Gray" Opacity="0.5" />
        </telerik:MapPinPoint.Background>
    </telerik:MapPinPoint>
</DataTemplate>

The ClusterItemGenerator has some automation to extract location from the data. But in the case of the arbitrary class (like it is in your code) generator can't do it without additional settings. You should inform it how to extract location from the custom object. For example:

public MainWindow()
  
{
    InitializeComponent();   
  
    // ...   
  
    ClusteredDataSource dataSource = this.informationLayer.ClusteredDataSource;
    ClusterItemGenerator generator = dataSource.ClusterItemGenerator as ClusterItemGenerator;
    generator.DataMappings.Add(new DataMapping("Location", DataMember.Location));   
  
    // ...  
}


Kind regards,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Mehmet
Top achievements
Rank 1
answered on 19 Jul 2012, 08:29 AM
Hi Andrey,

Thanks for your reply, that really solved my problem.

Have a nice day.
Tags
Map
Asked by
Mehmet
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Mehmet
Top achievements
Rank 1
Share this question
or