The given key is not present in the Xamarin Forms dictionary

I'm working on data binding for a Xamarin forms project using Xaml for the UI. So far it's 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>

      

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 the view model and use the bind command to navigate to another page when the button is clicked. The error I get is "The given key was not in the dictionary" when trying to build. I have isolated the problem for the line:<viewModels:DeviceCheckViewModel/>

I don't know why this error is happening.

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 following this route is to stick to the MVVM architecture. Therefore, placing the page navigation in the code behind is not an option. Also just notice that all Models, Models, and View Views are in a folder structure with the same names.

Any help would be greatly appreciated.

+3


source to share


2 answers


You set the binding context in your code behind:

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

      

So you don't need to do xaml-way either. This also instantiates DeviceCheckViewModel

and sets it as the binding context:



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

      

But , so it must have a parameterless constructor. This may be the reason for the execution you are receiving.

+9


source


I know this is an older topic, but when I ran into the same problem, I was not satisfied that the given answer was actually acceptable to me. I also prefer to keep this type of anchor in markup; keeping the code to a minimum.

What worked for me was to remove the XamlCompilation (...) attribute for the code behind the class. Try removing this attribute from your DeviceCheck class.



I also noticed that most of the code behind the classes has this attribute, but that only gives a problem to some of them.

0


source







All Articles