Move MapItem on InformationLayer

7 posts, 0 answers
  1. alireza
    alireza avatar
    1 posts
    Member since:
    Feb 2011

    Posted 07 Dec 2011 Link to this post

    Hi
    base on this tutorial :http://www.telerik.com/help/wpf/radmap-features-data-binding.html
    I Implemented INotifyPropertyChange for MapItem
    public class MapItem : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members
        void OnPropertyChanged(string prop)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
    and change their Location with this line of code
    private void button1_Click(object sender, RoutedEventArgs e)
          {
              foreach (MapItem item in infLayerMovingObjects.ItemsSource)
              {
                  Location loc = item.Location;
                  loc.Latitude += 0.001;
                  loc.Longitude += 0.001;
                  item.Location = loc;
              }
          }

    but it does not work ,
    how should I have to Refresh LayerInformation ?
    why LayerInformation does not notice about change in its obesrvable collection ?
    thanks.
  2. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 12 Dec 2011 Link to this post

    Hi Alireza,

    It is hard to say what is wrong with your implementation having just the code you've provided. Here it is an example of how it can be done. I hope it will help you understand the difference.

    The data item class:

    public class PointOfInterest : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
     
        private Location location;
        private string title;
        private string description;
     
        public Location Location
        {
            get
            {
                return this.location;
            }
     
            set
            {
                this.location = value;
                this.NotifyPropertyChanged("Location");
            }
        }
     
        public string Title
        {
            get
            {
                return this.title;
            }
     
            set
            {
                this.title = value;
                this.NotifyPropertyChanged("Title");
            }
        }
     
        public string Description
        {
            get
            {
                return this.description;
            }
     
            set
            {
                this.description = value;
                this.NotifyPropertyChanged("Description");
            }
        }
     
        protected void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    Main window XAML and code behind:

    <UserControl x:Class="ClickablePinpoint.MainPage"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 mc:Ignorable="d"
                 d:DesignHeight="300" d:DesignWidth="400">
         
        <UserControl.Resources>
            <DataTemplate x:Key="PoiTemplate">
                <Border telerik:MapLayer.Location="{Binding Location}"
                        Background="White"
                        BorderBrush="Black"
                        BorderThickness="1">
                    <Grid Width="20" Height="20" Margin="5">
                        <TextBlock Grid.Row="0"
                                   Text="{Binding Title}"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"/>
                    </Grid>
                </Border>
            </DataTemplate>
        </UserControl.Resources>
     
        <Grid x:Name="LayoutRoot" Background="White">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
             
            <telerik:RadMap x:Name="radMap"
                            Center="42.5,-99"
                            ZoomLevel="7">
                <telerik:RadMap.Provider>
                    <telerik:OpenStreetMapProvider />
                </telerik:RadMap.Provider>
                <telerik:InformationLayer x:Name="informationLayer"
                          ItemTemplate="{StaticResource PoiTemplate}" />
            </telerik:RadMap>
             
            <Button Grid.Column="1"
                    VerticalAlignment="Top"
                    Click="DoAction">
                <TextBlock Text="DoAction" />
            </Button>
        </Grid>
    </UserControl>



    public partial class MainPage : UserControl
    {
        private ObservableCollection<PointOfInterest> collection = new ObservableCollection<PointOfInterest>();
     
        public MainPage()
        {
            InitializeComponent();
     
            // Add data points
            PointOfInterest poi = new PointOfInterest()
            {
                Location = new Location(41.5, -101),
                Title = "#1",
                Description = "Descr. #1"
            };
            collection.Add(poi);
     
            poi = new PointOfInterest()
            {
                Location = new Location(42, -100),
                Title = "#2",
                Description = "Descr. #2"
            };
            collection.Add(poi);
     
            poi = new PointOfInterest()
            {
                Location = new Location(42.5, -99),
                Title = "#3",
                Description = "Descr. #3"
            };
            collection.Add(poi);
     
            this.informationLayer.ItemsSource = collection;
        }
     
        private void DoAction(object sender, RoutedEventArgs e)
        {
            foreach (PointOfInterest poi in this.collection)
            {
                Location loc = poi.Location;
                loc.Latitude += 0.01;
                loc.Longitude += 0.01;
                poi.Location = loc;
            }
        }
    }

    If this doesn't helps, please, send us a simple application which demonstrates the problem you have so we could check what is wrong and help you.

    All the best,
    Andrey Murzov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. UI for WPF is Visual Studio 2017 Ready
  4. SondreB
    SondreB avatar
    3 posts
    Member since:
    Nov 2006

    Posted 18 Jun 2013 Link to this post

    This works fine for a normal InformationLayer, but using the ClusteredDataSource stops the changes to the properties to be visible in the map. After my push pin have first been rendered, I'm unable to move it or change it in any way by manipulating the object.

    How would I go ahead and move a push pin rendered using the ClusteredDataSource? I'm not talking about the cluster pin, but the regular pins I'm showing when the user have zoomed the view.

    Is there any way to fix this?
  5. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 18 Jun 2013 Link to this post

    Hi Sondre,

    It is very complicated and it is hard to reproduce the problem without your solution or code.
    Could you, please, provide us with a small sample solution which reproduces it?

    Regards,
    Andrey Murzov
    Telerik

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  6. SondreB
    SondreB avatar
    3 posts
    Member since:
    Nov 2006

    Posted 18 Jun 2013 Link to this post

    Here is an attached example based upon the code above in this thread. I noticed another issue, and that is that the Title property is not binded properly as well, so that might be a clue. In the example, there are 6 points rendered, 3 of them binded directly to the InformationLayer, and the 3 others through a view model binded with the ClusteredDataSource. All items are rendered, but the 3 with ClusteredDataSource is missing it's Title and they don't move when the Location is changed.

    Download the project source here: https://www.wetransfer.com/downloads/37074d9930467b1c4601731d03f60b9f20130618114532/f7ead64838af47551ce121d0a9ee72be20130618114532/7722be
  7. Andrey
    Admin
    Andrey avatar
    1681 posts

    Posted 19 Jun 2013 Link to this post

    Hello Sondre,

    When you use the ClusteredDataSource for the InformationLayer then the items of the layer (clusters and single elements) are not updated automatically in a case when location of items which are bound to the ClusteredDataSource are updated. You should invoke the ClusteredDataSource.Refresh method after the items changed to refresh the layer. You can use a code like following at end of your DoAction method:
    private void DoAction(object sender, RoutedEventArgs e)
    {
        foreach (PointOfInterest poi in this.collection)
        {
            Location loc = poi.Location;
            loc.Latitude += 0.01;
            loc.Longitude += 0.01;
            poi.Location = loc;
        }
     
        var vm = (SomeViewModel)DataContext;
     
        foreach (PointOfInterest poi in vm.Items)
        {
            Location loc = poi.Location;
            loc.Latitude += 0.01;
            loc.Longitude += 0.01;
            poi.Location = loc;
        }
     
        this.pinsLayer.ClusteredDataSource.Refresh();
    }

    Also in a case with using the ClusteredDataSource the Title property should be bound using a path to the Data property. The sample data template is below.
    <DataTemplate x:Key="PoiTemplate2">
        <Border telerik:MapLayer.Location="{Binding Location}"
                Background="White"
                BorderBrush="Black"
                BorderThickness="1">
            <Grid Width="20" Height="20" Margin="5">
                <TextBlock Grid.Row="0"
                           Text="{Binding Path=Data.Title}"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center"/>
            </Grid>
        </Border>
    </DataTemplate>

    Regards,
    Andrey Murzov
    Telerik

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  8. SondreB
    SondreB avatar
    3 posts
    Member since:
    Nov 2006

    Posted 19 Jun 2013 Link to this post

    Great, thanks! Works perfectly :-)

    Only one slight issue, I can no longer reuse the same DataTemplate when I have multiple layers with the same push pin template, due to the "Data." mapped property. Other than that, excellent!
Back to Top
UI for WPF is Visual Studio 2017 Ready