Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given Key Not Present in Dictionary Xamarin Forms

Tags:

c#

xaml

xamarin

Im working on data binding for a Xamarin forms project using Xaml for the UI. So far its very simple:

XAML:

<?xml version="1.0" encoding="utf-8" ?>

xmlns:viewModels="clr-namespace:Watson.ViewModels;assembly=Watson"
         x:Class="Watson.Views.DeviceCheck">

<ContentPage.BindingContext>
    <viewModels:DeviceCheckViewModel/>
</ContentPage.BindingContext>

    <!--<ActivityIndicator Color="Red" IsRunning="True"
                   x:Name="loadingScreen"/>-->
<StackLayout>
    <Label Text="Checking Device.."/>

    <Button Text="page nav"
            Command="{Binding NextButton}"></Button>
</StackLayout>

The code behind:

namespace Watson.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DeviceCheck:ContentPage
    {

    private DeviceCheckViewModel viewModel;
    public DeviceCheck() {
        InitializeComponent();

        BindingContext = viewModel = new DeviceCheckViewModel(this.Navigation);


    }// end of constructor     

}// end of class

}// end of namespace

This is trying to bind to a view model and use a binding command to go to another page on a button click. The error I am getting is 'The given key was not present in the dictionary', this is when attempting a build. I have isolated the problem to the line: <viewModels:DeviceCheckViewModel/>

I have no idea why this error is occurring.

This is the view model:

namespace Watson.ViewModels
{
    public class DeviceCheckViewModel: INotifyPropertyChanged
    {
        public INavigation Navigation { get; set; }
        public ICommand NextButton { protected set; get; }

    public DeviceCheckViewModel(INavigation navigation)
    {
        this.Navigation = navigation;
        this.NextButton = new Command(async () => await GotoNextPage());

    }

    public async Task GotoNextPage()
    {

        await Navigation.PushAsync(new RegisterDevice());
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this,
                new PropertyChangedEventArgs(propertyName));
    }
}
}

The reason I am pursuing this route is to adhere to the MVVM architecture. So putting page navigation in the code behind is not really an option. Also just a note, all the models, view models and views are in a folder structure with the same names.

Any help would be appreciated.

like image 529
user3355961 Avatar asked Dec 13 '22 22:12

user3355961


1 Answers

You set the binding context in your code behind:

BindingContext = viewModel = new DeviceCheckViewModel(this.Navigation);

So there's no need to do the xaml-way, too. This also creates an instance of DeviceCheckViewModel and sets it as binding context:

<ContentPage.BindingContext>
    <viewModels:DeviceCheckViewModel/>
</ContentPage.BindingContext>

But, therefore it needs to have a parameterless constructor. This may be the reason for the excepetion you get.

like image 143
S. Spindler Avatar answered Dec 29 '22 11:12

S. Spindler