why is my Listview ItemsSource null (uwp app c#)

1.1k views Asked by At

I'm trying to bind a List in my ViewModel to a ListView in my Page but I can't get it to work, the ItemsSource is always null allthough the list is populated with values.

This is how I set the whole thing up.

theese attributes are added to the page tag in my xaml

xmlns:viewmodels ="using:TimeMachine3.ViewModels"
d:DataContext="{d:DesignInstance viewmodels:MasterViewModel}"

My LisstView is defined as

<ListView x:Name="lstMainMaster" ItemsSource="{Binding MyList}" SelectionChanged="lstMainMaster_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{x:Bind Name}"/>
                    <TextBlock Text="{x:Bind Number}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

In my master.cs (the page code) I have

    private ViewModels.MasterViewModel viewmodel;

    //constructor
    public master()
    {
        this.InitializeComponent();
        this.Loaded += Master_Loaded;
    }

    private void Master_Loaded(object sender, RoutedEventArgs e)
    {
        viewmodel = new ViewModels.MasterViewModel();
        viewmodel.populate();
    }

And in masterViewmodel (the viewmodel of the page) I have this code

    private ObservableCollection<Month> _myList;
    public ObservableCollection<Month> MyList{ get {return _myList; } }

    public void Populate()
    {
        _myList = new ObservableCollection<Month>(DataBase.GetMonths(2017));
    }
2

There are 2 answers

0
narancha On BEST ANSWER

I just realized that I dont have to implement the InotifyChanged interface if my DataContext is set up properly.

I changed the way the data context is set up from

xmlns:viewmodels ="using:TimeMachine3.ViewModels"
enter code here`d:DataContext="{d:DesignInstance viewmodels:MasterViewModel}"

To

<Page
...
xmlns:viewmodels ="using:TimeMachine3.ViewModels"
.../>
<Page.DataContext>
   <viewmodels:MasterViewModel>
</Page.DataContext>

And now the itemssource will be set right after the call to InitializeComponent() and if my list is altered then my ListView will update without adding more code (I don't even have to implement INotifyChanged)

4
Scroog1 On

It is null because you change the reference that MyList points to after you have loaded the view and don't notify the view of the change (via INotifyPropertyChanged). Therefore, the view does not know it needs to refresh the binding.

public void Populate()
{
    _myList = new ObservableCollection<Month>(DataBase.GetMonths(2017));
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyList)));
}

Or equivalent.