2haloes
2haloes

Reputation: 23

Avalonia UI Error in binding "Could not find CLR property"

I am trying to create an MVVM application which pulls data from an API and puts the data into lists which are used to navigate the program.

The issue I'm having is that the list produces this error and I cannot figure out why:

Binding: Error in binding to "Avalonia.Controls.TextBlock"."Text": "Could not find CLR property 'name' on 'attributes'"

For context, the 'attributes' class contains the 'name' variable and I have confirmed that the name variable is populated beforehand (the program printed the name variable before I moved onto trying to form a list).

XAML code (MainWindow.xaml):

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:RT_Stream_App.ViewModels;assembly=RT_Stream_App"
        Icon="resm:RT_Stream_App.Assets.avalonia-logo.ico"
        Title="RT Stream App">

  <Design.DataContext>
    <vm:MainWindowViewModel/>
  </Design.DataContext>

  <ListBox Items="{Binding CompanyList}" HorizontalAlignment="Left" Width="512" Height="512" Margin="20,20,0,10" VerticalAlignment="Top">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel DataContext="attributes">
          <TextBlock Text="{Binding name}" TextAlignment="Center" />
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
  <!-- <TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>  -->


</Window>

MainWindowViewModel.cs

namespace RT_Stream_App.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        // use => instead of = for assigning
        // public string Greeting => "I am testing!";

        public companies.APIData siteList => loadCompanies();

        //public string Greeting => TestLoop(siteList);
        public ObservableCollection<companies.companyData> CompanyList => siteList.data;

        public companies.APIData loadCompanies()
        {
            // This takes the API data for companies and converts it into a useable class
            companies.APIData toReturn = JsonConvert.DeserializeObject<companies.APIData>(new WebClient().DownloadString("https://svod-be.roosterteeth.com/api/v1/channels"));
            return toReturn;
        }
    }
}

Class data (companies.cs):

namespace RT_Stream_App.Classes
{

public class companies
{
    /// <summary>
    /// Root of the JSON
    /// </summary>
    public class APIData
    {
        public ObservableCollection<companyData> data = new ObservableCollection<companyData>();
    }

    /// <summary>
    /// A class that holds the data for each company (Name and link mostly)
    /// </summary>
    public class companyData
    {
        public attributeData attributes = new attributeData();
        public linkData links = new linkData();
    }

    /// <summary>
    /// Contains the company name
    /// </summary>
    public class attributeData
    {
        public string name { get; set; }
    }

    /// <summary>
    /// Contains link data for the next step
    /// </summary>
    public class linkData
    {
        public string shows { get; set; }
    }


}
}

What am I doing wrong and what needs to be changed?

Update: I have tried changing the DataTemplate in the XAML to the following:

<DataTemplate>
        <StackPanel>
          <TextBlock Text="{Binding attributes.name}" TextAlignment="Center" />
        </StackPanel>
      </DataTemplate>

Which produces this error:

Binding: Error in binding to "Avalonia.Controls.TextBlock"."Text": "Could not find CLR property 'attributes'

<DataTemplate>
        <StackPanel DataContext="{Binding attributes}">
          <TextBlock Text="{Binding name}" TextAlignment="Center" />
        </StackPanel>
      </DataTemplate>

Produces this error:

Binding: Error in binding to "Avalonia.Controls.StackPanel"."DataContext": "Could not find CLR property 'attributes'


Fix update: From Kekekeks answer, I figured out why my program wasn't working and now lists load. Due to using JSON.NET, I was worried about using constructors but I made the following change to all of my classes and the program displays the intended list

Class data (companies.cs) Updated: public class APIData {

            public APIData()
            {
                this.data = new ObservableCollection<companyData>();
            }
            public ObservableCollection<companyData> data {
                get;
                set;
                }
            }

Upvotes: 1

Views: 1828

Answers (1)

kekekeks
kekekeks

Reputation: 3623

You are setting a string "attributes" as your DataContext. Then Binding can't find the property "name" on System.String.

Remove DataContext="attributes" and replace your binding with Text="{Binding attributes.name}"

Upvotes: 1

Related Questions