Reputation: 99
How to get value from DatePicker and set it in variable in ViewModel? In my xaml file I have date picker like:
<DatePicker x:Name="dateTo"
TextColor="White"
FontSize="Small"
Date="{Binding DateTo}"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
IsVisible="{Binding DateToPickerVisibility}"
Margin="5,0,0,0"
IsEnabled="False"/>
In my ViewModel I have property
public DateTime DateTo { get; set; }
and set it's value in InidData method:
DateTo = DateTime.Now.Date.AddDays(1);
But how to change that value when date is changed and "OK" button on picker is clicked?
Upvotes: 1
Views: 3385
Reputation: 13843
Yes, your ViewModel need to implement INotifyPropertyChanged
,so that the DatePicker could update the value automatically.
There is a full demo which works properly. The main code is :
public class DateViewModel: INotifyPropertyChanged
{
bool _dateToPickerVisibility;
public bool DateToPickerVisibility
{
set { SetProperty(ref _dateToPickerVisibility, value); }
get { return _dateToPickerVisibility; }
}
DateTime _dateTo;
public DateTime DateTo
{
set { SetProperty(ref _dateTo, value); }
get { return _dateTo; }
}
public DateViewModel()
{
DateTo = DateTime.Now.Date.AddDays(1);
DateToPickerVisibility = true;
}
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;
}
MainPage.xaml
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="Start">
<DatePicker x:Name="dateTo"
FontSize="Small"
Date="{Binding DateTo}"
HorizontalOptions="StartAndExpand"
VerticalOptions="Start"
IsVisible="{Binding DateToPickerVisibility}"
Margin="5,0,0,0"/>
<Button x:Name="mButton"
Text="Hide DatePicker"
Clicked="MButton_Clicked"
VerticalOptions="Center"
/>
</StackLayout>
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
DateViewModel dateViewModel;
public MainPage()
{
InitializeComponent();
dateViewModel = new DateViewModel();
BindingContext = dateViewModel;
}
private void MButton_Clicked(object sender, EventArgs e)
{
if (dateViewModel.DateToPickerVisibility) {
dateViewModel.DateToPickerVisibility = false;
mButton.Text = "Make DatePicker visible";
}
else {
dateViewModel.DateToPickerVisibility = true;
mButton.Text = "Hide DatePicker";
}
}
}
Note:
1.You can init the value in the constructor of your ViewModel.e.g.
public DateViewModel()
{
DateTo = DateTime.Now.Date.AddDays(1);
DateToPickerVisibility = true;
}
2.To make the datePicker visible or hidden, I added a Button to change the value of DateToPickerVisibility
.
private void MButton_Clicked(object sender, EventArgs e)
{
if (dateViewModel.DateToPickerVisibility) {
dateViewModel.DateToPickerVisibility = false;
mButton.Text = "Make DatePicker visible";
}
else {
dateViewModel.DateToPickerVisibility = true;
mButton.Text = "Hide DatePicker";
}
}
The result is :
Upvotes: 1
Reputation: 15340
Your XAML looks fine.
Your property in the ViewModel, however, isn't invoking PropertyChanged
. When the value of a Property in the ViewModel changes, it needs to call PropertyChanged?.Invoke
to alert/update the View.
Here's an example of the XAML, its Code-Behind and its ViewModel:
<DatePicker x:Name="dateTo"
TextColor="White"
FontSize="Small"
Date="{Binding DateTo}"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
IsVisible="{Binding DateToPickerVisibility}"
Margin="5,0,0,0"
IsEnabled="False"/>
public partial class MyView
{
InitializeComponent();
BindingContext = new MyViewModel();
}
public class MyViewModel : INotifyPropertyChanged
{
bool _dateToPickerVisibility
DateTime _dateTo
public event PropertyChangedEventHandler PropertyChanged;
public DateTime DateTo
{
get => _dateTo;
set
{
_dateTo = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DateTo)));
}
}
public bool DateToPickerVisibility
{
get => _dateToPickerVisibility;
set
{
_dateToPickerVisibility = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DateToPickerVisibility)));
}
}
}
Upvotes: 0