I have a form with a datepicker and a timepicker which both are bound to the same property from the model
here my simple Model:
private DateTime _end;
[Required]
public DateTime End
{
get
{
return _end;
}
set
{
_end = value;
RaisePropertyChanged(() => End);
}
}
the viewmodel has a property of the ModelObject.
My XAML looks like this
<sdk:DatePicker SelectedDate="{Binding Path=CurrentAppointment.End, Mode=TwoWay}"/>
<toolkit:TimePicker Value="{Binding Path=CurrentAppointment.End, Mode=TwoWay}" />
is there a simple way to precent the time from changing when i pick the date (it always goes back to 00:00 because the datepicker sets the date to 2011-04-29 00:00:00) or do i have to make a property for the time in my model and put the date and the time together when i want to put it in my database?
This question is exactly the same as
Using silverlight datepicker and timepicker together
Use Converter
You could either decide not to use data-binding and implement your logic with events, or you could use a converter and bind its parameter to the TimePicker. When you change the date, you can parse the parameter and attach it to the datetime.
Related
Simplified Question:
I have a datepicker in WPF. I enter a value 30/10/1983 in the textbox of the datepicker. I need the value to be posted back to my viewmodel, where in I have bound it to a DateTime? property.
Is there any way I can achieve this. mm/dd/yyyy format triggers a postback but not dd/mm/yyyy.
The DatePicker code is as below.
<DatePicker Grid.Row="2" Name="inputDate"
Text="{Binding BirthDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
>
</DatePicker>
The view model property is as below.
private DateTime? birthDate;
public DateTime? BirthDate
{
get
{
return this.birthDate;
}
set
{
this.birthDate = value;
OnPropertyChanged("BirthDate");
}
}
I enter a value 10/10 into the datepicker textbox, the setter gets called with a value, but the moment I enter an entire date 30/10/1983, I still have the view model property which is equal to NULL.
I have changed the Format to English-UnitedKingdom, in the calendar settings, and my CurrentCulture reflects en-GB appropriately.
Original Question:
I have a datetimepicker control in WPF, which I have bound the text property to a Nullable DateTime in the view model.
The problem I am facing is when I enter a value in the format MM/dd/yyyy, I do get a value postback in the view model, indicating the new value.
But when I enter the value in dd/MM/yyyy format, I do not get a notification in the view model and the value is lost. The bound propertyin the view model is null.
The short date format is the one which I have specified in the calendar settings & dateFormat, within which for a short date format I provide the entry as "dd/MM/yyyy".
Could someone please help me with this scenario where in I accept date in dd/MM/yyyy format, and I do not want to hardcode, I wish to pick up the short date format from the calendar settings and also, I wish to recieve the updated value in the view model too.
The problem is related that a not valid date will not set with a correct value your ViewModel DateTime property. So, you can intercept it and convert correctly with a CONVERTER.
An example:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string strValue = System.Convert.ToString(value);
DateTime resultDateTime;
if (DateTime.TryParse(strValue, out resultDateTime))
{
return resultDateTime;
}
return value;
}
And your XAML code will be like:
<DatePicker
Text="{Binding BirthDate,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedDate="{Binding RelativeSource={RelativeSource Self},Path=Text,
Converter={StaticResource DateConverter}}"
/>
In my View.xaml I have a DatePicker bound to ViewModel's Date property
<DatePicker SelectedDate="{Binding Path=Date, Mode=TwoWay, Converter={StaticResource IfNullDateConverter}}" />
When View.xaml shown "IfNullConverter" is used to convert default DateTime value "01.01.0001" to DateTime.Now, so DatePicker displays current date. But actually the SelectedDate property is not set. Why?
When I press Save button, the DatePicker value passed to ViewModel is still "01.01.0001".
Please help, what am I doing wrong? How do I update my source code to pass current date if the date is "01.01.0001"?
IfNullDateConverter
DateTime dateValue = (DateTime)value;
if (dateValue.ToShortDateString() == "01.01.0001")
{
return DateTime.Now;
}
else
{
return value;
}
This is the right behavior. You should use converter when you want to convert the source value( Date in VM) and then set desdination(SelectedDate) with the new value. Which means that when you convert the source value, the result doesnt affect it, just the destination.
Conclusion : if you want to set a default value DateTime.Now to your property, you should do it in your VM
I want to implement two types of validation in my silverlight application. I want "business-logic" rules to be implemented in viewmodel(like end date is not earlier than start date) which i have already accomplished, and input validation somewhere on main control, where input fields are(like date is in bad format). Is there anything silverlight can "help" me with? I mean there is at least UnsetValue there for me, but is there any event associated or i have to catch all OnChanged events? Also is there a way to manually display red border around control when i want to?
Sorry, it was not obvious from my question, but i finished with the part that includes "business-logic" rules - my viewmodel indeed implements INotifyDataErrorInfo, i'm troubled with second type of validation.
Implement INotifyDataErrorInfo on your ViewModel to enable validation on View Model level.
Implement INotifyDataErrorInfo on your properties
then on your property that is binded in XAML use a friendly display name:
private DateTime? _datumP = DateTime.Now;
[Display(Name = "Date", ResourceType = typeof(CommonExpressions))]
public DateTime? DatumP
{
get
{
return _datumP;
}
set
{
if (_datumP != value)
{
_datumP = value;
RaisePropertyChanged(DatumPonudbePropertyName);
}
ValidateDate(DatumPonudbe, DatumPonudbePropertyName);
}
}
Then your method to validate dates:
public void ValidateDate(DateTime? value, string propertyName)
{
RemoveError(propertyName, CommonErrors.DatumNull_ERROR);
if (value == null)
AddError(propertyName, CommonErrors.DatumNull_ERROR, false);
}
And now for the XAML part:
<sdk:DatePicker Width="100" SelectedDate="{Binding DatumP, Mode=TwoWay,
NotifyOnValidationError=True, ValidatesOnNotifyDataErrors=True,
ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" />
P.S.
CommonExpressions and CommonErrors are my Resource files for multilanguage, you can use plain strings here.
I'm trying to validate the selected date in a datetime picker control and setting it to today's date if the date selected is > Datetime.Today.The issue I'm facing is that I'm not able to set the SelectedDate property of a datetimepicker control via xaml.I feel something is wrong with my binding, please can you help?
Following is the code.Please can you tell me what 'am I doing wrong?
<Controls:DatePicker Height="20"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
x:Name="dateControl"
IsTodayHighlighted="True"
Margin="5,10,5,20"
SelectedDate="{Binding Path=BindingDate, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
public class Context : INotifyPropertyChanged
{
public Context() { }
private DateTime bindingDate = DateTime.Today;
public DateTime BindingDate
{
get
{
return bindingDate;
}
set
{
if (DateTime.Compare(DateTime.Today, value) < 0)
{
MessageBox.Show("Please Select Today date or older, Should not select future date");
//This is not reflected anytime in SelectedDate property of the control, why???
value = DateTime.Today;
}
bindingDate = value;
OnPropertyChanged("BindingDate");
}
}
..and yes I'm setting the datacontext of the window like the following:
public Window1()
{
InitializeComponent();
this.DataContext = new Context();
}
Any suggestions would be highly appreciated.
Thanks,
-Mike
That is because the BindingDate setter will never be called if you set value for your local variable bindingDate and your ui will never be notified.
Instead of setting
private DateTime bindingDate = DateTime.Today.AddDays(13);
try setting
BindingDate = DateTime.Today.AddDays(13);
EDIT
But selecting a future date in the datepicker will remain even after showing the messagebox because the selection is already made in the control and will not reset back.
But you can consider other alternatives like blocking all future dates from selection by using the BlackoutDates or DisplayDates property of the datepicker or you can conside using custom validation rules as mentioned in the below post
Date picker validation WPF
You could consider implementing INotifyPropertyChanging also, and not only INotifyPropertyChanged.
In that way you can alsol notify that your property is about to change, and run some code accordingly.
And of course notify that your property has effectively changed.
How to apply validations to WPF datepicker toolkit? I want it to error out if invalid date is selected and in some case I have Arrival and Departure dates, so I want to validate it to see that the arrival date is not later than the departure date.
It seems a year above date picker validation was a problem. Anyway, now it works.
I am not a WPF specialist, bu I'll try to give you an idea
write a validation rule
public class DateExpiredRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
DateTime orderDate = (DateTime)value;
return new ValidationResult(orderDate < DateTime.Now, "Please, enter date before Now()");
}
}
then you can attach it to datepicker
<!-- since validation works hand by hand with binding,
I use hidden datepicker as binding source -->
<WPFToolkit:DatePicker Name="dateProvider" Visibility="Collapsed">
</WPFToolkit:DatePicker>
<WPFToolkit:DatePicker Name="notExpired">
<WPFToolkit:DatePicker.SelectedDate>
<Binding ElementName="dateProvider" Path="SelectedDate" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:DateExpiredRule/>
</Binding.ValidationRules>
</Binding>
</WPFToolkit:DatePicker.SelectedDate>
</WPFToolkit:DatePicker>
specify control template when validation error occurs. By default validation error changes border color. I used additional tooltip when mouse is over control.
source code
About 'picker to picker' validation.
I know that one can use custom properties in validation rules (see AgeRangeRule in msdn example)
Maybe you should use this feature like this
<local:MaxDateRule MaxDate="{Binding ElementName=DepartureDatePicker, Path=SelectedDate" />
but in order to apply binding you need to make MaxDate a DependencyProperty .. you should definetly ask a guru ;)
Instead of highlighting you should consider intercepting the datepicker value change (via some kind of datepicker 'onchange' event) and accept or reject the change.