-1

I have a class, that represents a line in a table, as:

public class TeamListModel
{
    public uint TeamId {get;set;}
    public string TeamName {get;set;}
    
    public string NamesOfPlayers {get;set;}
    
    public uint? Score {get;set;}
    
    public bool IsChecked { get; set; }
}

In the view model I fetch the data from a service, and I create an ObservableCollection from it (adding only the relevant code here):

public partial class ListTeamsViewModel(ITeamService teamService): ObservableObject
{
    public IAsyncRelayCommand AppearingCommand => new AsyncRelayCommand(OnAppearingAsync);

    [ObservableProperty]
    private ObservableCollection<TeamListModel> teams;

    private async Task OnAppearingAsync()
    {
        await LoadTeamsAsync();
    }

    private async Task LoadTeamsAsync()
    {
        var result = await teamService.GetPagedAsync(page);

        if (result.IsError)
        {
            await Application.Current.MainPage.DisplayAlert("Error", "Teams are not loaded!", "OK");
            return;
        }

        Teams = new ObservableCollection<TeamListModel>(result.Value.Items);
    }
}

The part of the view where I am displaying the list looks like this (again only the relevant part):

<CollectionView ItemsSource ="{Binding Teams}" Margin="150">
     <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="listModels:TeamListModel">
            <components:TemListComponent Team="{Binding .}" 
                                         DeleteCommand="{Binding Source={RelativeSource AncestorType={x:Type viewModels:ListTeamsViewModel}}, Path=DeleteCommand}"
                                         CommandParameter="{Binding TeamId}"/>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

As you can see, I am using a TemListComponent component, that looks like this:

public partial class TemListComponent : ContentPage
{
    public static readonly BindableProperty TeamProperty = BindableProperty.Create(
           propertyName: nameof(Team),
           returnType: typeof(TeamListModel),
           declaringType: typeof(TemListComponent),
           defaultValue: null,
           defaultBindingMode: BindingMode.OneWay);

    public TeamListModel Team
    {
        get => (TeamListModel)GetValue(TeamProperty);
        set => SetValue(TeamProperty, value);
    }

    public static readonly BindableProperty DeleteCommandProperty = BindableProperty.Create(
        propertyName: nameof(DeleteCommand),
        returnType: typeof(IAsyncRelayCommand),
        declaringType: typeof(TemListComponent),
        defaultValue: null,
        defaultBindingMode: BindingMode.OneWay);

    public IAsyncRelayCommand DeleteCommand
    {
        get => (IAsyncRelayCommand)GetValue(DeleteCommandProperty);
        set => SetValue(DeleteCommandProperty, value);
    }

    public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create(
        propertyName: nameof(CommandParameter),
        returnType: typeof(string),
        declaringType: typeof(TemListComponent),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay);

    public uint CommandParameter
    {
        get => (uint)GetValue(CommandParameterProperty);
        set => SetValue(CommandParameterProperty, value);
    }

    public IAsyncRelayCommand EditCommand => new AsyncRelayCommand(OnEditAsync);

    public TemListComponent()
    {
        InitializeComponent();
    }

    private async Task OnEditAsync()
    {
        ShellNavigationQueryParameters navigationQueryParameter = new ShellNavigationQueryParameters
        {
            {
                "Team",this.Team
            }
        };
        Shell.Current.ClearNavigationStack();
        await Shell.Current.GoToAsync(CreateOrEditTeamView.Name, navigationQueryParameter);
    }
}

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Solution.DesktopApp.Components.TemListComponent"
             x:Name="this"
             Title="TemListComponent">
    <Border Padding="10,0,10,0">
        <Grid Padding="10,0,10,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="50"/>
            </Grid.ColumnDefinitions>

            <Label  Grid.Column="0"
             Text="{Binding Team.TeamName, Source={x:Reference this}}"
             HorizontalTextAlignment="Center"
              VerticalTextAlignment="Center"
              TextColor="Red"/>
            
            <Label  Grid.Column="1"
             Text="{Binding Team.NamesOfPlayers, Source={x:Reference this}}"
             HorizontalTextAlignment="Center"
             VerticalTextAlignment="Center"/>

            <Label  Grid.Column="2"
             Text="{Binding Team.Score, Source={x:Reference this}}"
             HorizontalTextAlignment="End"
             VerticalTextAlignment="Center"/>
            
            <ImageButton Source="edit.png"
                      Grid.Column="5"
                      Command="{Binding EditCommand, Source={x:Reference this}}"
                      HorizontalOptions="Center"
                      VerticalOptions="Center"
                      WidthRequest="25"
                      HeightRequest="25"/>
        </Grid>
    </Border>
</ContentPage>

The error occurs when I try to create a new instance of the ObservableCollection from the data that I received from the service, and the error says System.Runtime.InteropServices.COMException that doesn't tells a lot what is a problem. I tried to hardcode one value to the collection and I got the same result.

thnx

1
  • Because it is an observable property! Commented May 23 at 20:44

1 Answer 1

0

At the end I found the error, the component was inherited from page not from ContentView.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.