Search code examples
c#listviewmaui

MAUI: ListView Binding With Custom ViewCell


I use FreshMvvm to develop and run MAUI project on Windows.

But I have some binding issues with ListView and my custom template.

The following is my code:

Model:

public class BaseModel
{
    public string Code{ get; set; }
}

public class NameModel: BaseModel
{
    public string Name{ get; set; }
}

ViewModel:

public class MainPageModel : FreshBasePageModel
{
    private readonly IApiService _apiService;
    private List<NameModel> _nameModelList;

    public List<NameModel> NameModelList
    {
        get => _nameModelList;
        private set 
        {
            _nameModelList= value;

            RaisePropertyChanged(nameof(NameModelList));
        }
    }

    public MainPageModel(IApiService apiService)
    {
        _apiService = apiService;
    }

    protected override void ViewIsAppearing(object sender, EventArgs e)
    {
        base.ViewIsAppearing(sender, e);

        Task.Run(() => GetNameData());
    }

    private async Task GetNameData()
    {
        var result = await _apiService.GetNameData();
        NameModelList= result.GetRange(1, 10);
    }
}

I create a list and use an api service to get a name model list data. If api service gets the data, NameModelList will be updated.

NameModelList is the property which will be bind on Listview.ItemsSource

MainPage.xmal:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyNamespace.ViewCells.CustomListViewCell"
             x:Class="MyNamespace.Pages.MainPage"
             BackgroundColor="{DynamicResource SecondaryColor}">

    <Grid RowSpacing="25" 
          RowDefinitions="Auto" 
          VerticalOptions="FillAndExpand"
          HorizontalOptions="FillAndExpand">

        <ListView 
                x:Name="MyListView"
                ItemsSource="{Binding NameModelList}"
                Grid.Row="0"
                WidthRequest="800"
                HeightRequest="800"
                BackgroundColor="Gray"
                VerticalOptions="FillAndExpand"
                HorizontalOptions="FillAndExpand">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <local:MyCustomViewCell/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </Grid>
</ContentPage>

Custom ViewCell (.xml):

<ViewCell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          x:Class="MyNamespace.ViewCells.CustomListViewCell.MyCustomViewCell">

    <Grid RowSpacing="100"  WidthRequest="100" HeightRequest="100">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100*" />
        </Grid.ColumnDefinitions>
        <StackLayout
            GridLayout.Row="0"
            GridLayout.Column="0">
            <Label
                Text="{Binding Code}"
                FontSize="30"/>
            <Label
                Text="{Binding Name}"
                FontSize="30"/>
        </StackLayout>
    </Grid>
</ViewCell>

Custom ViewCell (.cs)

public partial class MyCustomViewCell: ViewCell
{
    public static readonly BindableProperty CodeProperty = 
        BindableProperty.Create("Code", typeof(string), typeof(MyCustomViewCell), "");

    public string Code
    {
        get { return (string)GetValue(CodeProperty); }
        set { SetValue(CodeProperty, value); }
    }

    public static readonly BindableProperty NameProperty =
        BindableProperty.Create("Name", typeof(string), typeof(MyCustomViewCell), "");

    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }
}

I define a custom ViewCell files and put this ViewCell in the Listview of MainPage.

Now my question is my Listview can't show data successfully.

I'm sure that NameModelList has value and its count is more than 1.

But I can see nothing.

The output log has no error, and the breakpoints in MyCustomViewCell.cs are never triggered.

So I think I have some binding issues, but I can't find it out.


Solution

  • To get to the bottom of this I took your code and put it in a project so I could have a little play with it. You can find the repo here. Not to be rude here or anything, but might be a good idea for a next question to do that yourself, that will help speed things up :)

    Anyway, the problem is much more subtle. Because you're using XAML for your layout, you'll have to call InitializeComponent in the constructor. So adding this to your MyCustomViewCell made it work:

    public MyCustomViewCell()
    {
        InitializeComponent();
    }