button dosent bind with SelectedDate, to ble to be able

Eduardo Gomez Romero 225 Reputation points
2024-07-08T17:00:23.51+00:00

I have created a custom control

<ContentView
    x:Class="customDatePicker.Controls.DateTimeZonePicker"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:icon="clr-namespace:customDatePicker"
    xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    xmlns:picker="clr-namespace:Syncfusion.Maui.Picker;assembly=Syncfusion.Maui.Picker"
    xmlns:syncfusion="clr-namespace:Syncfusion.Maui.Popup;assembly=Syncfusion.Maui.Popup"
    xmlns:sys="clr-namespace:System;assembly=System.Runtime"
    x:Name="DateTmeZone">

    <Grid
        Margin="20"
        ColumnDefinitions="*,*"
        RowDefinitions="350,60,*">
        <Label Text="Select date an time" />
        <Label
            Grid.Column="1"
            FontFamily="Material"
            FontSize="32"
            HorizontalTextAlignment="End"
            Text="{Static icon:IconFont.Date_range}">
            <Label.Behaviors>
                <mct:TouchBehavior Command="{Binding OpenDateTime, Source={x:Reference DateTmeZone}}" />
            </Label.Behaviors>
        </Label>
        <picker:SfDateTimePicker
            Grid.Column="1"
            DateFormat="dd_MMM_yyyy"
            HeightRequest="350"
            HorizontalOptions="End"
            IsVisible="{Binding IsDateTimePickerVisible, Source={x:Reference DateTmeZone}}"
            MinimumDate="{Static sys:DateTime.Now}"
            SelectedDate="{Binding SelectedDate, Source={x:Reference DateTmeZone}}"
            TimeFormat="HH_mm"
            VerticalOptions="Start"
            WidthRequest="350">
            <picker:SfDateTimePicker.HeaderView>

                <picker:DateTimePickerHeaderView
                    DateFormat="MMM/dd/yyyy"
                    TimeFormat="HH:mm" />

            </picker:SfDateTimePicker.HeaderView>

            <picker:SfDateTimePicker.FooterView>

                <picker:PickerFooterView
                    Height="40"
                    OkButtonText="Select date"
                    ShowOkButton="True" />

            </picker:SfDateTimePicker.FooterView>

            <picker:SfDateTimePicker.Behaviors>
                <mct:EventToCommandBehavior
                    Command="{Binding OkButtonClickedCommand, Source={x:Reference DateTmeZone}}"
                    EventName="OkButtonClicked" />
                <mct:EventToCommandBehavior
                    Command="{Binding CancelButtonClickedCommand, Source={x:Reference DateTmeZone}}"
                    EventName="CancelButtonClicked" />
            </picker:SfDateTimePicker.Behaviors>
        </picker:SfDateTimePicker>
        <Label
            Grid.Row="1"
            Text="Time Zone"
            VerticalTextAlignment="Center" />
        <Picker
            Title="Choose your timezone"
            Grid.Row="1"
            Grid.Column="1"
            FontAttributes="Bold"
            ItemsSource="{Binding Timezones, Source={x:Reference DateTmeZone}}"
            SelectedItem="{Binding SelectedTimeZone, Source={x:Reference DateTmeZone}}" />

        <Button
            Grid.Row="2"
            Grid.Column="2"
            IsEnabled="{Binding IsButtonEnabled, Source={x:Reference DateTmeZone}}"
            Text="{Binding ButtonText, Source={x:Reference DateTmeZone}}"
            VerticalOptions="EndAndExpand" />
    </Grid>
</ContentView>

public partial class DateTimeZonePicker : ContentView {
    public DateTimeZonePicker() {
        InitializeComponent();
    }
    public static readonly BindableProperty ButtonTextProperty = BindableProperty.Create(
        nameof(ButtonText), typeof(string), typeof(DateTimeZonePicker));
    public string ButtonText {
        get => (string)GetValue(ButtonTextProperty);
        set => SetValue(ButtonTextProperty, value);
    }
    public static readonly BindableProperty IsButtonEnabledProperty = BindableProperty.Create(
        nameof(IsButtonEnabled), typeof(bool), typeof(DateTimeZonePicker));
    public bool IsButtonEnabled {
        get => (bool)GetValue(IsButtonEnabledProperty);
        set => SetValue(IsButtonEnabledProperty, value);
    }
    public static readonly BindableProperty SelectedDateProperty = BindableProperty.Create(
        nameof(SelectedDate), typeof(DateTime), typeof(DateTimeZonePicker));
    public DateTime SelectedDate {
        get => (DateTime)GetValue(SelectedDateProperty);
        set => SetValue(SelectedDateProperty, value);
    }
    public static readonly BindableProperty TimezonesProperty = BindableProperty.Create(
        nameof(Timezones), typeof(List<string>), typeof(DateTimeZonePicker));
    public List<string> Timezones {
        get => (List<string>)GetValue(TimezonesProperty);
        set => SetValue(TimezonesProperty, value);
    }
    public static readonly BindableProperty SelectedTimeZoneProperty = BindableProperty.Create(
        nameof(SelectedTimeZone), typeof(string), typeof(DateTimeZonePicker));
    public string SelectedTimeZone {
        get => (string)GetValue(SelectedTimeZoneProperty);
        set => SetValue(SelectedTimeZoneProperty, value);
    }
    public static readonly BindableProperty IsDateTimePickerVisibleProperty = BindableProperty.Create(
        nameof(IsDateTimePickerVisible), typeof(bool), typeof(DateTimeZonePicker));
    public bool IsDateTimePickerVisible {
        get => (bool)GetValue(IsDateTimePickerVisibleProperty);
        set => SetValue(IsDateTimePickerVisibleProperty, value);
    }
    public static readonly BindableProperty OpenDateTimeProperty = BindableProperty.Create(
        nameof(OpenDateTime), typeof(RelayCommand), typeof(DateTimeZonePicker));
    public RelayCommand OpenDateTime {
        get => (RelayCommand)GetValue(OpenDateTimeProperty);
        set => SetValue(OpenDateTimeProperty, value);
    }
    public static readonly BindableProperty OkButtonClickedCommandProperty = BindableProperty.Create(
        nameof(OkButtonClickedCommand), typeof(RelayCommand), typeof(DateTimeZonePicker));
    public RelayCommand OkButtonClickedCommand {
        get => (RelayCommand)GetValue(OkButtonClickedCommandProperty);
        set => SetValue(OkButtonClickedCommandProperty, value);
    }
    public static readonly BindableProperty CancelButtonClickedCommandProperty = BindableProperty.Create(
        nameof(CancelButtonClickedCommand), typeof(RelayCommand), typeof(DateTimeZonePicker));
    public RelayCommand CancelButtonClickedCommand {
        get => (RelayCommand)GetValue(CancelButtonClickedCommandProperty);
        set => SetValue(CancelButtonClickedCommandProperty, value);
    }
}


But for some reason doesn't want to bind

    [ObservableProperty]
    bool isPickerVisible;
    [ObservableProperty]
    [NotifyPropertyChangedFor(nameof(ButtonText), nameof(IsButtonEnabled))]
    DateTime? selectedDateTime = null;
    [ObservableProperty]
    [NotifyPropertyChangedFor(nameof(IsButtonEnabled))]
    String selectedTimeZone;
    public List<string> Timezones { get; set; }
    public string ButtonText => SelectedDateTime.HasValue ? $"Schedule for {SelectedDateTime:MMMM dd yyyy 'at' HH:mm}" : "";
    public bool IsButtonEnabled => SelectedDateTime.HasValue && !string.IsNullOrEmpty(SelectedTimeZone);
    public MainViewModel() {
        GetTimeZones();
    }
    private void GetTimeZones() {
        Timezones =
            [
                // US Time Zones
                "America/Adak",
                "America/Anchorage",
                "America/Boise",
                "America/Chicago",
                "America/Denver",
                "America/Detroit",
                // Add more US time zones as needed
                // Other Time Zones
                "America/Caracas",
                "America/Guayaquil",
                "Europe/Madrid",
                "Asia/Riyadh"
                // Add more time zones as needed
            ];
    }
    [RelayCommand]
    void OpenDateTimePicker() {
        IsPickerVisible = true;
    }
    [RelayCommand]
    void OkButtonClicked() {
        IsPickerVisible = false;
    }
    [RelayCommand]
    void CancelButtonClicked() {
        IsPickerVisible = false;
    }
    [RelayCommand]
    void ScheduleButtonClicked() {
        //TODO: Schedule the meeting, taking into account the time zone 
    }
}

every time I select moment and put a breakpoint is null

image

User's image

the picker is opening and hiding with

 [RelayCommand]
    void OkButtonClicked() {
        IsPickerVisible = false;
    }
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,157 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 71,671 Reputation points Microsoft Vendor
    2024-07-09T06:37:04.81+00:00

    Hello,

    What I do not understand is that I have to put two ways in xml, when i already put

    • TwoWay — data goes both ways between source and target
    • OneWay — data goes from source to target

    From this document:Binding mode - .NET MAUI | Microsoft Learn

    When data bindings are used with the Model-View-ViewModel (MVVM) pattern, the viewmodel class is the data-binding source, and the view, which consists of views are data-binding targets.

    By default, the binding mode is OneWay, data goes from source to target(ViewModel to View).

    If you want each view on the page to be initialized with the value of the corresponding property in the viewmodel, but changes in the view should also affect the viewmodel property, you need to change the binding mode to Two way.

    If you set the TwoWay in the contentview's xml, data can go between ContentView's child controls and the contentview background code's BindableProperty.

    And you set the TwoWay in the BindableProperty, data can go between the ContentView and the Viewmodels. In the end, if you want data can go between ContentView's child controls and viewmodel, please set both of them.

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.