Paul Stanley
Paul Stanley

Reputation: 2161

UWP TimePicker MVVM

I am having problems getting the Time property of the TimePicker into my ViewModel.The method on the ViewModel

TimePickerTimeSelected()

is called but BEFORE the Time property is updated.

private DateTimeOffset _datePickerValue;
public DateTimeOffset datePickerValue
 {
     get => _datePickerValue;
     set => SetProperty(ref _datePickerValue, value);
 }

Here isthe XAML

<TimePicker
     Name="timePicker"
     Time="{x:Bind viewModel.timePickerValue,Mode=TwoWay}"
     TimeChanged="{x:Bind viewModel.TimePickerTimeSelected,Mode=TwoWay}">

I want to do some processing with the time when it is selected in the control but the method is called before the timePickerValue is updated.How do I get the new time? ViewModel method:

  public void TimePickerTimeSelected()
  {

  }

Upvotes: 0

Views: 374

Answers (1)

Dishant
Dishant

Reputation: 1595

In your Xaml you are setting Mode=TwoWay to TimeChanged Event which is invalid, as TmeChange is an Event and not a DependencyProperty.

In order to achieve the desired output please refer to the below code:

Xaml:

<TimePicker
   Name="timePicker"
   Time="{x:Bind ViewModel.TimePickerValue, Mode=TwoWay}"
   TimeChanged="{x:Bind ViewModel.TestTimeChangedEvent}"/>

ViewModel:

  private TimeSpan _timePickerValue;
  public TimeSpan TimePickerValue
  {
     get { return _timePickerValue; }
     set { _timePickerValue = value;}
  }

  public void TestTimeChangedEvent(object sender, TimePickerValueChangedEventArgs e)
  {
     TimePickerValue = e.NewTime;
  }

EDIT

As you don't want to use TimePickerValueChangedEventArgs in your ViewModel, you have to create a custom behavior to get the selected time in your VM.

XAML:

 <TimePicker
     Name="timePicker">
    <Interactivity:Interaction.Behaviors>
       <behaviors:TimeChangedEventBehavior/>
    </Interactivity:Interaction.Behaviors>
 </TimePicker>

Behavior:

  public sealed class TimeChangedEventBehavior : DependencyObject, IBehavior
    {
        public DependencyObject AssociatedObject { get; private set; }

        public void Attach(DependencyObject associatedObject)
        {
            if (!(associatedObject is TimePicker tp))
            {
                throw new ArgumentException("Error Associating Object");
            }

            this.AssociatedObject = associatedObject;

            tp.TimeChanged += OnTimeChanged;
        }

        private void OnTimeChanged(object sender, TimePickerValueChangedEventArgs e)
        {
            var timePicker = (sender as TimePicker);
            var mainVM = (timePicker.DataContext as MainViewModel);
            mainVM.OnTimePickerTimeSelected(timePicker.Time);
        }

        public void Detach()
        {
            if (this.AssociatedObject is TimePicker tp)
            {
                tp.TimeChanged -= this.OnTimeChanged;
            }
        }
    }

ViewModel:

 public void OnTimePickerTimeSelected(TimeSpan selectedTime)
 {
     // Your Logic       
 }

Upvotes: 1

Related Questions