This project has moved. For the latest updates, please go here.

Binding to ZoomLevel of Map in another Window

Jan 19, 2013 at 3:34 PM
Edited Jan 19, 2013 at 3:34 PM

Hello ClemensF,

I must annoy you another time... But I can't achieve to bind a little map in an extra window to the zoomlevel from the big map.

Here's what I tried:

<map:Map Name="map" IsManipulationEnabled="False"
                 LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
                 Center="0.0,0.0" ZoomLevel="{Binding Path=Owner.map.ZoomLevel, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
                 TileLayer="{Binding Source={x:Static local:Settings.mapsourcefordisplay}}">

 

This map is located in a window whose owner locates the other map.

I hope you can help me, I don't know what to do after one hour of searching in the internet...

 

Regards, ialokim

Coordinator
Jan 19, 2013 at 5:57 PM
Edited Jan 19, 2013 at 5:58 PM

Do you observe any binding error messages in the Output Window of Visual Studio?

In your binding you haven’t set any Source or RelativeSource, so Owner must be a public property of the object that is the current DataContext. Moreover it would have to be a class that itself has another public property map.

I guess that map is just a XAML-declared field (by setting Name=”map”) in another window. Create a public property in that other window like this:

public MapBase Map { get { return map; } }

and change the binding to

{Binding Path=Owner.Map.ZoomLevel ...}

Cheers
Clemens

Jan 20, 2013 at 9:52 AM

Thanks for your quick reply, but it don't want to work like this. I've set the Binding like this:

 

ZoomLevel="{Binding Path=Owner.Map.ZoomLevel, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"

 

And the public property in the MainWindow Class like this:

        public Map Map
        {
            get { return map; }
            set
            {
                map = value;
                OnPropertyChanged("Map");
            }
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
How could I do the binding with Source or RelativeSource? Sorry, I'm not such good in WPF Bindings...

However, I would like to have the second map always to or three zoomlevels smaller than the main-map, so that's like an overview map. I think, I'll need a multibindingconverter or what?

 

Cheers,

Ialokim

 

PS. I've found this error message in the Output Window:

System.Windows.Data Error: 40 : BindingExpression path error: 'Owner' property not found on 'object' ''String' (HashCode=-1321543336)'. BindingExpression:Path=Owner.Map.ZoomLevel; DataItem='String' (HashCode=-1321543336); target element is 'Map' (Name='map'); target property is 'ZoomLevel' (type 'Double')

Coordinator
Jan 20, 2013 at 12:46 PM
Edited Jan 20, 2013 at 12:48 PM

The error message says it all. Your current DataContext seems to be a string, which of course has no Owner property. What do you expect Owner to be? As I've written before, there should be some class that has a Owner property, which perhaps contains an instance of your MainWindow class with it's Map property, but how could I possibly know that?

Your problem is out of scope here. You should make yourself familiar with data binding in WPF. There are tons of resources on the web.

Jan 28, 2013 at 6:24 PM
Edited Jan 28, 2013 at 6:25 PM

I've achieved now to bind the zoom property by creating a class with the properties currentzoom and currentzoomoverview:

 

 public double currentzoom
{
get { return _currentzoom; }
  set { _currentzoom = value; OnPropertyChanged("currentzoom"); OnPropertyChanged("currentzoomoverview"); }
 }
public double currentzoomoverview
{
get { double _currentzoomoverview = _currentzoom - 2.0; return _currentzoomoverview; }
}

Then, I've binded in my MainWindow:

 

<map:Map Name="map" IsManipulationEnabled="True"
                 LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
                 Center="0.0"
                 ZoomLevel="{Binding Source={StaticResource settings}, Path=currentzoomoverview, UpdateSourceTrigger=PropertyChanged}">

 

 

and in my OverviewMapWindow:

<map:Map Grid.Column="2" Grid.Row="1" Name="map" IsManipulationEnabled="True"
                 LightForeground="Black" LightBackground="White" DarkForeground="White" DarkBackground="#FF3F3F3F"
                 Center="0.0"
                 ZoomLevel="{Binding Source={StaticResource settings}, Path=currentzoom, Mode=OneWayToSource}">

This worked pretty well for me, but there's one thing: if you zoom in the MainWindow with your mousewheel, the zoomlevel changes again if you stop to turn the wheel: sometimes, the zoom becomes smaller and sometimes bigger, but there's always such a surge. I don't know if you can understand my problem, but probably you could try my approach.

 

Regards, ialokim

Coordinator
Jan 28, 2013 at 6:47 PM

You might also bind the TargetZoomLevel property instead of ZoomLevel. TargetZoomLevel is changed during a mouse wheel event by the amount given by the MouseWheelZoomChange property. ZoomLevel is then continuously changed by an internal animation until it reaches the value of ZoomLevel.