public class DataContextProxy : Freezable { #region Overrides of Freezable protected override Freezable CreateInstanceCore() { return new DataContextProxy(); } #endregion public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(DataContextProxy), new UIPropertyMetadata(null)); }
<esri:Map> <esri:Map.Resources> <local:DataContextProxy x:Key="proxy" Data="{Binding}" /> </esri:Map.Resources> <esri:ArcGISTiledMapServiceLayer ID="PhysicalTiledLayer" Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"/> <esri:GraphicsLayer ID="MyGraphicsLayer" GraphicsSource="{Binding Path=Data.SearchResults, Source={StaticResource proxy}}" Renderer="{StaticResource MySimpleRenderer}" /> </esri:Map>
At my knowledge, the issue here is that you need to explicitly define source for your binding when binding from non-visual elements (layers in this case) to something. Since layers aren't part of the visual tree, they do not get the DataContext derived from the upper elements so we need to proxy the DataContext somehow to the non-visual elements in XAML.
Why use a workaround when you can just utilize the "Binding" keyword and make the platform do all the rest of the work for you?
Sheled,DependencyObject's don't provide a DataContext, but they can still participate in data binding so they work great in MVVM. The trick is to specify the Source in your binding statement. For a FrameworkElement there is an implicit source (the DataContext) but for a DependencyObject you have to declare it explicitly.There are different techniques to do this. In the following example, I declare the ViewModel as a resource in the View and then I can use the StaticResource approach: <Window.Resources> <local:MainViewModel x:Key="MainViewModel" /> </Window.Resources> <Grid DataContext="{StaticResource MainViewModel}"> <esri:Map Extent="-14268281.1311858,2195120.17402859,-7232639.54776086,7467160.93387503"> <esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" /> <esri:GraphicsLayer ID="MyGraphicsLayer" GraphicsSource="{Binding SearchResults, Source={StaticResource MainViewModel}}"/> </esri:Map> </Grid> Hopefully that does the trick for you./Jeff
<Window.Resources> <local:MainViewModel x:Key="MainViewModel" /> </Window.Resources> <Grid DataContext="{StaticResource MainViewModel}"> <esri:Map Extent="-14268281.1311858,2195120.17402859,-7232639.54776086,7467160.93387503"> <esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer" /> <esri:GraphicsLayer ID="MyGraphicsLayer" GraphicsSource="{Binding SearchResults, Source={StaticResource MainViewModel}}"/> </esri:Map> </Grid>
Antti,I love this solution! Very clean and works like a champ.Thanks for the tip.-Jeff
To original poster,If the post answered to your problem, please mark to answered.
<esri:Map IsLogoVisible="False" x:Name="MapObject" Grid.Row="1"> <Mapping:LocalOpenStreetMapLayer Style="Mapnik" /> <Controls:AutoGpsLayer x:Name="AutoGpsLayer" Bearing="{Binding Bearing,Mode=OneWay}" /> </esri:Map>
public double Bearing { get { return _bearing; } set { _bearing = value; NotifyOfPropertyChange(()=>Bearing);} }
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Bearing; DataItem=null; target element is 'AutoGpsLayer' (HashCode=22325283); target property is 'Bearing' (type 'Double')
Los miembros registrados pueden publicar, seguir actualizaciones y más. ¿Nuevo aquí? Regístrate gratis.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.