Select to view content in your preferred language

Binding Zoom Controls to Map with MVVM setup

1076
3
05-22-2012 12:13 PM
ErnieSalazar
New Contributor III
Hi guys.  Have another question.  This one is about working with custom zoom controls to act on a Map control when everything is wired with MVVM.  Running in SL4.

Right now, I have my View which contains the Map control.  The layers of the map control is bound to a property of the view model thatwill load up layers on start.  Works great.  I was also able to create a Navigation control in the View (in XAML) which is bound to the Map.  That works as well.

But what if I wanted to instead of using a Nav control create a set of images or buttons that control the zoom.  Say Zoom Extent, in, out, etc.  Can I wire the button directly to the Map control in XAML or does it have to pass back to the ViewModel through some kind of command binding?

If it has to be through the viewmodel, how to do I wire that up?  I read that the Map.Extent is not bindable.  I also read that I can create the MapExtentHelper dependency to deal with this but didn't couldn't quite get my head around how to implement it.

Thanks
Ernie
0 Kudos
3 Replies
vipulsoni
Occasional Contributor
Hi guys.  Have another question.  This one is about working with custom zoom controls to act on a Map control when everything is wired with MVVM.  Running in SL4.

Right now, I have my View which contains the Map control.  The layers of the map control is bound to a property of the view model thatwill load up layers on start.  Works great.  I was also able to create a Navigation control in the View (in XAML) which is bound to the Map.  That works as well.

But what if I wanted to instead of using a Nav control create a set of images or buttons that control the zoom.  Say Zoom Extent, in, out, etc.  Can I wire the button directly to the Map control in XAML or does it have to pass back to the ViewModel through some kind of command binding?

If it has to be through the viewmodel, how to do I wire that up?  I read that the Map.Extent is not bindable.  I also read that I can create the MapExtentHelper dependency to deal with this but didn't couldn't quite get my head around how to implement it.

Thanks
Ernie


Hi,

I guess what you require here I had seen a similar approach in one of the Navigation Toolbar sample from ESRI and in that sample a navigation toolbar user control is present which is wired to the mainpage.xaml containing the map. Unfortunately I dont have the download link of the sample but I remember that navigation toolbar containing the zoom in and out buttons was referenced from mainpage.xaml by calling two methods  -

MyNavToolbar.SetParent(this);
  MyNavToolbar.SetMap(Mapcontrol);

and in the navigationtoolbar the methods are -

public void SetParent(MainPage TheParent)
        {
            // Assumes that MainPage supports SetCursor and UnsetTool
            _Parent = TheParent;
        }

        public void SetMap(Map TheMap)
        {
            _Map = TheMap;
            _Map.ExtentChanged += _Map_ExtentChanged;
            _Map.MouseClick += _Map_MouseClick;
            _ZoomDrawObject = new Draw(_Map) { FillSymbol = DefaultFillSymbol, DrawMode = DrawMode.Rectangle };
            _ZoomDrawObject.DrawComplete += _ZoomDrawObject_DrawComplete;
        }

this can only help you as a pointer.
0 Kudos
ErnieSalazar
New Contributor III
Thanks Vipul.  So it seems that I have to do it in the code behind of the View?  Cant really think of a way to have the Map control in the View but being able to access the extent in the viewmodel AND have custom buttons in XAML.

Ernie
0 Kudos
JoeHershman
MVP Regular Contributor
I am not exactly clear on what you are describing with how the map is exposed in you view model.  You descriptions sounds as though you have a Layers collection on the ViewModel that is bound to the map in Xaml.  Something along these lines below.

<esri:Map x:Name="MyMap" WrapAround="True" Extent="-15000000,2000000,-7000000,8000000" Layers="{Binding MapLayers}">


I have found that it is pretty much impossible to really create an ESRI Silverlight API application without exposing the Map object to the ViewModel, there are just too many things that need the Map object.  What I do is have my main page implement an interface that exposes the Map.

    public interface IMapView
    {
        Map Map { get; }
    }


I use Dependency Injection (I use MEF, Unity is another Microsoft option) to get my IMapView object into my ViewModels.  I don't actually have a ViewModel attached to the MainPage, instead my MainPage is made of numerous views each with it's own ViewModel.

From here I would have a View (some kind of toolbar in this case) with an attached ViewModel.  For a good navigation tool you kind of need toggle buttons, in my opinion.  I have made those as custom controls that inherit from RadioButton.  RadioButton because it already includes the behavior of only one being selected at a time, compared to core ToggleButton.  There are a few ways to wire the commands, the most straight forward is to have the ViewModel expose an ICommand for each button and a bool for the IsSelected property.  Something similar to below

                <Buttons:MyToggleButton Text="{Binding Path=LanguageResource.ButtonText, Source={StaticResource LocalizedStrings}}" 
                                               IsChecked="{Binding ZoomInIsChecked, Mode=TwoWay}"
                                               Click="{Binding ZoomCommand}" CommandParameter="ZoomIn" GroupName="ZoomButtons"/>


        [Import]
        public IMapView MapView {get;set;}

        private ICommand _zoomCommand;
        public ICommand ZoomCommand
        {
            get { return _zoomCommand?? (_zoomCommand= new DelegateCommand<string>(ExecuteZoomCommand)); }
        }

        private void ExecuteZoomCommand(string zoomType)
        {
             //Here would be my zoom logic
        }




Something along those lines ties the Command to the view model

Hope that helps
Thanks,
-Joe
0 Kudos