FunkyPeanut
FunkyPeanut

Reputation: 1182

What is wrong with that binding?

I am working on a Windows 8 App using C# and Xaml as well as the MVVM-Light Toolkit.

I set everything up to create a proper binding to an ObservableCollection that gets its Data from a local database but it does not work well. It works when I edit the get property of the ObservableCollection to something like:

get
{
    _Subjects.Add(new SubjectViewModel { Name = "Test" });
    return _Subjects;
}

That displays the "Test"-Subject but still not the Subjects from the Database. Nevertheless - here is all the relevant code:

The Registration in the ViewModelLocator:

public ViewModelLocator()
{
    [...]
    SimpleIoc.Default.Register<MainViewModel>();
}

public MainViewModel Main
{
    get
    {
        return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
}

Get the Data from a Database:

Invokation:

public sealed partial class MainPage : Stundenplaner.Common.LayoutAwarePage
{
    MainViewModel mainViewModel = new MainViewModel();

    [...]

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        mainViewModel.GetSubjects();
        base.OnNavigatedTo(e);
    }
}

GetSubjects method and the ObservableCollection

public MainViewModel()
{
    _Subjects = new ObservableCollection<SubjectViewModel>();
}

public const string SubjectsPropertyName = "Subjects";
private ObservableCollection<SubjectViewModel> _Subjects = null; 

public ObservableCollection<SubjectViewModel> Subjects
{
    get
    {
        return _Subjects;
    }

    set
    {
        if (_Subjects == value)
        {
            return;
        }
        RaisePropertyChanging(SubjectsPropertyName);
        _Subjects = value;
        RaisePropertyChanged(SubjectsPropertyName);
    }
}

public void GetSubjects()
{
    using (var db = new SQLite.SQLiteConnection(App.DBPath))
    {
        var query = db.Table<Subject>().OrderBy(c => c.Name);
        foreach (var _subject in query)
        {
            var subject = new SubjectViewModel()
            {
                Id = _subject.Id,
                Name = _subject.Name
            };
            _Subjects.Add(subject);
        }
    }
}

The Binding to that Collection:

<GridView ItemsSource="{Binding Main.Subjects, Source={StaticResource Locator}}" [...]/>

EDIT
Thanks to Rohit Vats I've solved the problem now:

Insted of creating a new instance of the MainViewModel I've created an instance of the ViewModelLocator that accesses the registered instance of the MainViewModel like so:

ViewModelLocator Vml = new ViewModelLocator();

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    Vml.Main.GetSubjects();
    base.OnNavigatedTo(e);
}

Upvotes: 1

Views: 77

Answers (1)

Rohit Vats
Rohit Vats

Reputation: 81253

MainWindowViewModel instances are different that's why you database data not visible on GUI.

GridView is binded to Main -

public MainViewModel Main
{
    get
    {
        return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
}

ServiceLocator.Current.GetInstance<MainViewModel>(); will return new instance of MainWindowViewModel.

Whereas while navigating you are creating altogether new instance of MainWindowViewModel in MainPage and calling GetSubjects() on that instance.

You should create a single instance for MainWindowViewModel which will be shared between your View and MainPage.

Upvotes: 1

Related Questions