Search code examples
c#wpfmvvmmodel-view

Not Able to Bind Data From Read Only Property from View Model on View


I have a view-model Class which designed like this and I have a getter only property as

  public string TPKUri
    {
        get { return localMapService.UrlMapService; }
     }

now as you can see from the following image I am getting the UrlMapService url in the TPKUri

enter image description here

but when I am trying to get TPKUri value in the view. For example when I try something like this in the MainWindow.xaml

<Grid>
<Label Content="{Binding Source={StaticResource VM}, Path=BasemapUri}" />
</Grid>

it displays nothing.

class MainViewModel : INotifyPropertyChanged
{
    public Model myModel { get; set; }
    public LocalMapService localMapService;

    public event PropertyChangedEventHandler PropertyChanged;

    public MainViewModel()
    {
        myModel = new Model();
        CreateLocalService();
    }

    public string TPKUri
    {
        get { return localMapService.UrlMapService; }
     }

    public string MPKMap
    {
        get { return myModel.MPKPackage; }
        set
        {
            this.myModel.MPKPackage = value;
            OnPropertyChanged("MPKUri");
        }
    }
    public async void CreateLocalService()
    {
        localMapService = new LocalMapService(this.MPKMap);
        await localMapService.StartAsync();
    }


    protected void OnPropertyChanged([CallerMemberName] string member = "")
    {
        var eventHandler = PropertyChanged;
        if (eventHandler != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(member));
        }
    }
}

Here is the full MainWindow.xmal

<Window x:Class="MPK.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MPK.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
        <Window.Resources>
            <local:MainViewModel x:Key="VM"/>
        </Window.Resources>
    <Grid>
        <Label Content="{Binding Source={StaticResource VM}, Path=BasemapUri}" />
             <esri:MapView x:Name="MyMapView" Grid.Row="0"  LayerLoaded="MyMapView_LayerLoaded" >
            <esri:Map>
            <esri:ArcGISDynamicMapServiceLayer ID="Canada"  ServiceUri="{Binding Source={StaticResource VM}, Path=TPKUri}"/>
            </esri:Map>
        </esri:MapView>

    </Grid>
</Window>

Solution

  • Your localMapService.StartAsync(); is an async method but all your properties are not waiting for the results. So your XAML binding may get the values of the properties before your service complete starting.

    What you should do is to notify the property changes after your `localMapService.StartAsync();

    public async void CreateLocalService()
    {
        localMapService = new LocalMapService(this.MPKMap);
        await localMapService.StartAsync();
    
        // Notify that the service initialization is completed.
        OnPropertyChanged(nameof(TPKUri));
        OnPropertyChanged(nameof(MPKMap));
    }