Picker in CollectionView does not bind

Rask

Member
Joined
Mar 29, 2023
Messages
7
Programming Experience
5-10
Greetings all

Recently I dipped my finger in dotnet maui and C# for first time. So I run intro some issues. I am trying to follow MVVM model and make a collectionview that contains Labels and Pickers. The labels update as expected but the picker does not, it is empty.

C#:
<CollectionView BackgroundColor="IndianRed"
                            Grid.ColumnSpan="3"
                            Grid.Row="1"
                            SelectionMode="None"
                            ItemsSource="{Binding TestsObservableCollection}">
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="model:TestModelClass">
                        <Grid Padding="10">
                            <Frame HeightRequest="125">
                                <Grid Padding="1" ColumnDefinitions="*, 120">
                                    <VerticalStackLayout Grid.Column="0"
                                                         Padding="1" Spacing="1"
                                                         VerticalOptions="FillAndExpand">
                                        <HorizontalStackLayout Spacing="3">
                                            <Label Text="Test:">
                                            </Label>
                                            <Label Text="{Binding Name}">
                                            </Label>
                                        </HorizontalStackLayout>
                                        <HorizontalStackLayout Spacing="3">
                                            <Label Text="Location of test object:">
                                            </Label>
                                            <Label Text="{Binding Location}">
                                            </Label>
                                        </HorizontalStackLayout>
                                        <HorizontalStackLayout Spacing="3">
                                            <Label Text="Analog Value of test item:">
                                            </Label>
                                            <Label Text="{Binding Value}">
                                            </Label>
                                        </HorizontalStackLayout>
                                    </VerticalStackLayout>
                                    <Picker
                                        x:Name="testResultPicker"
                                        Grid.Row="0"
                                        Grid.Column="2"
                                        Title="Test Status"
                                        BackgroundColor="IndianRed"
                                        ItemDisplayBinding="{Binding Result}">
                                    </Picker>
                                </Grid>
                            </Frame>
                        </Grid>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

any suggestions?
 
Solution
I need a duck

C#:
                            ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewmode:MainPageViewModel}}, Path=PickerPossibleTestResult}"
                            ItemDisplayBinding ="{Binding testPossibleResult}"

I spend the entire day on a typo.. I was using the wrong AncestorType!
Where do you bind the ItemsSource for the Picker?
 
In my viewmodel the TestsObservableCollection is an ObservableCollection I am using communityMvvmToolkit.

So I did some testing. If I take the picker outside the collectionView then it works, as expected, but I have only one item.

What I want to do, is to have a collection of tests. A picker with test result options and then look at each selected test result, from SelectedItem of the picker.
 
I think I found the issue. My model was correct, but the way I was using it in the viewmodel was not.

What I was doing is that the Binding to Result was correct, but Result was always empty. So this was the first step to make me realize that something was wrong with my viewmodel.

I made a small solution in a new project, I will work on it a bit more and then see if I need help.

As I see it now I will need to move the picker outside as I need it an ObservableCollection of equal size of my TestsObservableCollection

In any case I will post an update so that people can refer to it.

Sorry for ranting but writing it down apparently help. :cool:
 
You just needed a rubber duck. I call up one of my co-workers all the time and tell them "I just need a rubber duck. Sit and listen." :)

As an aside, though, another thing that may help is going through the checklist on "How to ask questions the smart way". Often going through the list leads me to answer before I even get to ask the question officially.
 
OK I have it working as a stand alone. But I have no idea how to make a binding to a source.


view:
<?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="examples.MainPage"
             xmlns:viewmode="clr-namespace:examples.ViewModel"
             x:DataType="viewmode:MainPageViewModel"
             >
   
    <Grid RowDefinitions="125,auto,*"
          ColumnDefinitions="500,175"
          Padding="10"
          RowSpacing="10"
          ColumnSpacing="10"
          BackgroundColor="LightCoral">

        <Picker x:Name="picker" Title="Test Result"
                ItemsSource="{Binding PickerItems}"
                ItemDisplayBinding="{Binding testResult}"
                TextColor="Black"
                >
        </Picker>

        <Entry Placeholder="Entry text"
               Text="{Binding Text}"
               Grid.Column="1"
               Grid.Row="1"
               BackgroundColor="white">
        </Entry>

        <Button
            Text="Test Button"
            Grid.Row="0"
            Grid.Column="2"
            Command="{Binding AddCommand}"
            BackgroundColor="black">
        </Button>
        <CollectionView Grid.Row="2" Grid.ColumnSpan="2"
                        ItemsSource="{Binding Items}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="{x:Type x:String}">
                    <Grid ColumnDefinitions="100,300"
                          RowDefinitions="100,100">
                        <Label Grid.Row="1" Grid.Column="1" Text="this is a nice test">
                        </Label>
                        <Label Text="Test Items">
                        </Label>
                        <Picker Grid.Column="1" x:Name="picker" Title="Select a test result"
                            ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewmode:TestResultModel}}, Path=TestResultModel}"
                            ItemDisplayBinding="{Binding testResultModel}"
                            TextColor="Black">
                        </Picker>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>

</ContentPage>

viewmode and model:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Collections.ObjectModel;

namespace examples.ViewModel;

public partial class MainPageViewModel : ObservableObject
{
    public MainPageViewModel()
    {
        Items = new ObservableCollection<string>();
        PickerItems = new ObservableCollection<TestResultModel>();
    }

    [ObservableProperty]
    ObservableCollection<string> items;

    [ObservableProperty]
    ObservableCollection<TestResultModel> pickerItems;

    [ObservableProperty]
    string text;

    [RelayCommand]
    void Add()
    {
        Items.Add(text);
        PickerItems.Add(new TestResultModel() { testResult = text });
        Text = string.Empty;
    }

}

public class TestResultModel
{
    public string testResult { get; set; }
}
 
Last edited:
I need a duck

C#:
                            ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewmode:MainPageViewModel}}, Path=PickerPossibleTestResult}"
                            ItemDisplayBinding ="{Binding testPossibleResult}"

I spend the entire day on a typo.. I was using the wrong AncestorType!
 
Solution
Back
Top Bottom