.NET MAUI Communitytoolkit.Mvvm: How to bind an object instead of a string

1.4k Views Asked by At

i already the project from the official tutorial of .NET MAUI until step 5 using Communitytoolkit.Mvvm: text

Now, instead of binding only a Text (which is a standard type that can be accessed from everywhere) i would like to bind a simple object (called ItemGroup) with two members (bool isChecked and string name).

How to do that? For a global access i made this class in the MainView folder called ItemGroup. This class is not accessable and i don't know how to do that it is. I changed the code in the MainPage.xaml like this:

                <CollectionView ItemsSource="{Binding Items}"
                                Grid.Row="1">
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="{x:Type x:ViewModel.ItemGroup}">
                            <Grid >
                                <CheckBox IsChecked="{Binding ItemGroup.IsChecked}" Grid.Column="0"/>
                                <Label Text="{Binding ItemGroup.name}"  Padding="10" Grid.Column="1"                                                                  
                                    BackgroundColor="LightGray"/>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>

See also the project structure with the ItemGroup class in the ViewModel folder as well as the error message:

enter image description here

where the content page is declared as this:

enter image description here

Remark: The MainViewModel looks like this:

enter image description here

  • Should i declare some uses, or namespace?
  • where in the project should i place the Class of the objects i would bind?

Thanks in advance, Thomas

Also tryed to implement the class ItemGroup in the MainViewModel.cs but then i had any more problems with access to this class.

3

There are 3 best solutions below

6
On

I believe your problem lies with you Binding declaration inside you ItemTemplate. Given that you bound your CollectionView's ItemSource to "items", the ItemTemplate's data context is now a single itemGroup from your list. Therefore, you should not be writing

<CheckBox IsChecked="{Binding ItemGroup.IsChecked}"[...]

But instead

<CheckBox IsChecked="{Binding isChecked}"[...]

Since you are already "within" a single itemgroup object. Same goes for your Label. Furthermore, I don't think you actually need to declare the Datatype for your item's DataTemplate.

p.s. Watch out for your item declaration, it seems like you have both items and Items declared in your ViewModel; and both seem public.

0
On

Try this

<Label Text="{Binding name}" …

Note that name must be a public property

0
On

You have a number of issues here.

The community mvvm toolkit includes code generators.

A variable:

[ObservableProperty]    
string text;

Is examined by the code generator at compile time and in a partial class it will add a public property Text.

Binding is case sensitive and you need to bind to public properties so you need to use upper case on that first letter. Binding Text rather than Binding text.

You might have other instances where you did the same sort of thing.

I don't see where you use it but that add [Relaycommand] will generate AddCommand as a public property which you bind to.

Additionally you have misunderstood how an itemscontrol gets an item out a bound collection per row. As DevenCC points out, once you bind ItemsSource to Items then each row will get an instance of whatever is in that collection so you should bind IsChecked rather than ParentProperty.IsChecked.

As to where to put classes. In large apps it is a nuisance to flip between a folder contains views and another contains viewmodels. You might want to consider a folder contains each pair of view and viewmodel. Hence a foo folder containing fooView and fooViewModel