Home > Software engineering >  .NET MAUI pass picker value to ICommand
.NET MAUI pass picker value to ICommand

Time:11-21

I'm a beginner with .NET MAUI and I'm trying to pass a Picker value to an Icommand, but what I can receive is only this date 01/01/1900 The Icommand is fired but the date still 01/01/1900

This is my Xaml code:

<Picker
    HeightRequest="40"
    WidthRequest="150"
    Grid.Row="1" Grid.Column="1"
    BackgroundColor="Beige"
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    Title="Seleziona Il Mese"
    ItemsSource="{Binding Month}"
    IsVisible="{Binding visible}"
   

    >
    <Picker.Behaviors>
        <mct:EventToCommandBehavior
        EventName="SelectedIndexChanged"
        Command="{Binding SelectedMesi}"
        EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
        CommandParameter="SelectedItem"
            />
    </Picker.Behaviors>

And this is the viewModel

public DateTime datascelta { get; set; }
    public ICommand SelectedMesi { get; }

    public DateTime DataScelta
    {
        get => datascelta;
        set
        {
            if(value == datascelta) return;
            datascelta = value;
            OnPropertyChanged();
        }
    }
    internal void SelectedIndexChangeMese()
    {
         DataScelta = datascelta; 
    }

Where is the mistake?? Thx you.

CodePudding user response:

You will either need a property that works with SelectedItem or you can use pickers reference to do the same as well

For eg:

<Picker
x:Name="yourPicker"
HeightRequest="40"
WidthRequest="150"
Grid.Row="1" Grid.Column="1"
BackgroundColor="Beige"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
Title="Seleziona Il Mese"
ItemsSource="{Binding Month}"
IsVisible="{Binding visible}"


>
<Picker.Behaviors>
    <mct:EventToCommandBehavior
    EventName="SelectedIndexChanged"
    Command="{Binding SelectedMesi}"
    EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
    CommandParameter="{Binding SelectedItem, Source={x:Reference yourPicker}}"
        />
</Picker.Behaviors>

Good luck!

CodePudding user response:

You haven't set the SelectedItem property for your Picker.

Based on your code, I created a demo and achieved this function.You can refer to the following code:

MyViewModel .cs

public class MyViewModel : INotifyPropertyChanged 
{
    public List<Item> Datalist { get; set; }

    public DateTime datascelta { get; set; }
    public ICommand SelectedMesiCommand { get; set; }

    //public DateTime DataScelta
    //{
    //    get => datascelta;
    //    set
    //    {
    //        if (value == datascelta) return;
    //        datascelta = value;
    //        OnPropertyChanged();
    //    }
    //}

    Item _selectedItem;
    public Item SelectedItem
    {
        get => _selectedItem;
        set => SetProperty(ref _selectedItem, value);
    }

    public MyViewModel() {

        Datalist = new List<Item>();

        Datalist.Add(new Item { MyDateTime = new DateTime(2022,11,1).ToShortDateString()});
        Datalist.Add(new Item { MyDateTime = new DateTime(2022, 11, 2).ToShortDateString() });
        Datalist.Add(new Item { MyDateTime = new DateTime(2022, 11, 3).ToShortDateString() });
        Datalist.Add(new Item { MyDateTime = new DateTime(2022, 11, 4).ToShortDateString() });
        Datalist.Add(new Item { MyDateTime = new DateTime(2022, 11, 5).ToShortDateString() });
        Datalist.Add(new Item { MyDateTime = new DateTime(2022, 11, 6).ToShortDateString() });

        SelectedMesiCommand = new Command(testcommand);
    }

    private void testcommand(Object obj)
    {
        if (obj !=null && obj is MyViewModel) {

            MyViewModel item = (MyViewModel)obj;
        
            System.Diagnostics.Debug.WriteLine("the selected item is : "  SelectedItem.MyDateTime);
        }

    }

    //internal void SelectedIndexChangeMese()
    //{
    //    DataScelta = datascelta;
    //}

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Item.cs

public class Item
{
    public string MyDateTime { get; set; }
}

MainPage.xaml

<?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:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="MauiPickerApp1121.MainPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <toolkit:SelectedItemEventArgsConverter x:Key="SelectedItemEventArgsConverter" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Picker
    HeightRequest="40"
    WidthRequest="150"
    Grid.Row="1" Grid.Column="1"
    BackgroundColor="Beige"
    HorizontalOptions="Center"
    HorizontalTextAlignment="Center"
    Title="Seleziona Il Mese"
    ItemsSource="{Binding Datalist}"
    ItemDisplayBinding="{Binding MyDateTime}"
                
    SelectedItem="{Binding SelectedItem}"

    >
                <Picker.Behaviors>
                    <toolkit:EventToCommandBehavior
                    EventName="SelectedIndexChanged"
                    Command="{Binding SelectedMesiCommand}"
                    EventArgsConverter="{StaticResource SelectedItemEventArgsConverter}"
                    CommandParameter="{ Binding .}"
                />
                </Picker.Behaviors>

            </Picker>
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

MainPage.xaml.cs

public partial class MainPage : ContentPage 
{
      public MainPage()
      {
            InitializeComponent();

            this.BindingContext =  new MyViewModel();
      }
}

Note:

1.I can get the MyViewModel from command SelectedMesiCommand, and I can also get the updated SelectedItem.

   SelectedMesiCommand = new Command(testcommand);
    

    private void testcommand(Object obj)
    {
        if (obj !=null && obj is MyViewModel) {

            MyViewModel item = (MyViewModel)obj;
        
            System.Diagnostics.Debug.WriteLine("the selected item is : "  SelectedItem.MyDateTime);
        }

    }

2.In fact, you can also use DatePicker to achieve this.

  • Related