2

I ran into a problem by creating a reusable custom control with the CommunityToolkit.Mvvm package.

I have a page like this:

<?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"
             xmlns:viewModels="clr-namespace:XYZ.ViewModels"
             xmlns:cards="clr-namespace:XYZ.Cards"
             x:Class="XYZ.Pages.InboxPage"
             x:DataType="viewModels:InboxViewModel">
    <ScrollView>
        <VerticalStackLayout Margin="15">
            <CollectionView ItemsSource="{Binding Documents}">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <cards:DocumentPreviewCard
                            DocId="{Binding Id}"
                            Name="{Binding Name}"
                            ThumbnailUri="{Binding ThumbnailUrl}"/>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

With just that single line in my constructor in the code behind (the viewModel is injected):

BindingContext = viewModel;

This ViewModel contains a List of Models (Documents in the xaml above). The called custom control (DocumentPreviewCard) looks like this:

XAML:

<VerticalStackLayout
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:viewModels="clr-namespace:XYZ.ViewModels"
    x:Class="XYZ.Cards.DocumentPreviewCard"
    x:DataType="viewModels:DocumentPreviewViewModel"
    HeightRequest="270"
    WidthRequest="180"
    Margin="15">
    <Border>
        <Border.StrokeShape>
            <RoundRectangle CornerRadius="10"/>
        </Border.StrokeShape>
        <Image x:Name="ImgThumbnail"
                   HorizontalOptions="Center"
                   VerticalOptions="Center">
            <Image.Source>
                <UriImageSource Uri="{Binding ThumbnailUri}" />
            </Image.Source>
        </Image>
    </Border>
    <Label HorizontalTextAlignment="Center" 
                   Text="{Binding Name}" />
</VerticalStackLayout>

Code behind:

public partial class DocumentPreviewCard : VerticalStackLayout
{
    public DocumentPreviewCard()
    {
        BindingContext = new DocumentPreviewViewModel();
    }
}

ViewModel:

public partial class DocumentPreviewViewModel : ObservableObject
{
    [ObservableProperty]
    private bool _isLocked;

    [ObservableProperty]
    private string? _name;

    [ObservableProperty]
    private Guid? _docId;

    [ObservableProperty]
    private string? _thumbnailUri;
}

Unfortunately i cant access the following properties in the xaml of the page: DocId, Name, ThumbnailUri.

I got the error "No property, BindableProperty, or event found for "DocId", or mismatching type between value and property" for each of the wanted properties.

Has anyone had the same problem before, or an example of custom controls with MVVM and .Net Maui?

dominikz
  • 45
  • 5
  • 2
    IMHO, custom controls should not set a BindingContext. If they do, it will be hard for surrounding page to bind with them. Personally, I don't even associate a ViewModel with a custom control. I show [both with and without VM here](https://stackoverflow.com/a/72342037/199364). – ToolmakerSteve Sep 26 '22 at 18:27
  • Can you provide relevant codes about BindableProperty? – Hongxin Sui-MSFT Sep 27 '22 at 07:13

0 Answers0