Search code examples
c#data-bindinguwpdatacontext

Using binding and DataContext in UWP not working


I'm creating a mobile Windows app. I have a view in UWP which xaml.cs file starts with the following code:

using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using EnergyBattle.Helpers;

namespace EnergyBattle.Views.Tutorial
{
    public sealed partial class TutorialPage1 : Page
    {
        ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
        StorageFolder localFolder = ApplicationData.Current.LocalFolder;
        UniversalData VM = UniversalData.Instance;

        public TutorialPage1()
        {
            this.InitializeComponent();
            DataContext = VM;
        }

The corresponding view has the following markup code:

<Page
    x:Class="EnergyBattle.Views.Tutorial.TutorialPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:EnergyBattle.Views.Tutorial"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
        <TextBlock>Select your sportclub</TextBlock>

        <ListView ItemsSource="{Binding ListOfSportclubs}" IsItemClickEnabled="True" ItemClick="listItemClick">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Row="0" Grid.Column="0"><Run Text="{Binding name}" /></TextBlock>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Page>

I am trying to use the binding (as shown in "") to display items in a list that I have saved in a model. The DataContext has the correct data in it, as you can see at this breakpoint: https://i.sstatic.net/8TFVi.png - note that at this point, the emulator is still on its boot screen, so the view isn't yet loaded.

Surely, the ListView should be filled with al seven items in the DataContext, correct? For me, the view is showing nothing other than the test text, "Select your sportclub".

I get the following error message in my output window:

Error: BindingExpression path error: 'ListOfSportclubs' property not found on 'EnergyBattle.Helpers.UniversalData'. BindingExpression: Path='ListOfSportclubs' DataItem='EnergyBattle.Helpers.UniversalData'; target element is 'Windows.UI.Xaml.Controls.ListView' (Name='null'); target property is 'ItemsSource' (type 'Object')

What am I doing wrong? Very similar code works perfectly fine in other programs I've seen and worked on.

Edit: people want to know more about the ListOfSportclubs. Here it is defined:

class UniversalData
    {
        public static UniversalData Instance { get; } = new UniversalData();
        private List<Sportclub> ListOfSportclubs = new List<Sportclub>();
        private List<Stoplicht> stoplichtList = new List<Stoplicht>();

        public List<Sportclub> getSportclubList() { return ListOfSportclubs; }
        public List<Stoplicht> getStoplichtList() { return stoplichtList; }

        public void setSportclubList(List<Sportclub> sportclubList)
        {
            this.ListOfSportclubs = sportclubList;
        }

        public void setStoplichtList(List<Stoplicht> stoplichtList)
        {
            this.stoplichtList = stoplichtList;
        }
    }

Solution

  • As error says the property with this name is not found in your view model. Binding works with public properties, not with fields.

    In you screenshot you have ListOfSportclubs member in your view model, but due to error it is field.

    You need to create some public property in your view model and create binding to this property.

    public List<Sportclub> ListOfSportclubs { get; set; } = new List<Sportclub>();