Handle databound WPF datepicker ArgumentOutOfRangeException - wpf

I have a user control that handles both creating and editing an object. I'm setting a week of BlackOutDates on a DatePicker. If the date that the DatePicker's SelectedValue property is bound to falls on a blackout date, it throws an ArgumentOutOfRangeException (as is documented here: http://msdn.microsoft.com/en-us/library/system.windows.controls.datepicker.selecteddate%28VS.95%29.aspx).
How do I handle this exception when it is occurring during data binding? The binding's ExceptionValidationRule only handles exceptions that occur when updating the source property. Ideally I'd like to display whatever value is already set, but have it fail validation. Like if you had a textbox with a validation rule that said it only allows the letter "a". If you bind a property set to the string "zzzzz", it's not going to blow up the application and be incapable of displaying the value, it will just fail validation.

After thinking about it, I think I'm mistakenly mixing up the concepts of blackout dates and validation. The datepicker's blackout dates are a presentational feature, not a validation mechanism. So what I've done is when the control loads, if my bound object's date occurs on a blackout date, I don't black it out. You can't have a blacked out date selected, so this is the only option. In the selected date changed event handler, I reassess the blackout dates and black them out if the selected date no longer occurs on one. So once I choose a valid date, I can't change it back to a blacked out date. Then I added an additional validation rule to make sure the control can't save if the selected date occurs on an invalid date.

Related

Specify user input date format in WPF datepicker

I would like users to have an ability to type in dates in datepicker control. The two formats allowed are MMDDYYYY or MMDDYY, by default it is not possible to do it without slash
Dealing with this myself. Decided I wanted more of a "maskedtextbox" serving as my textbox versus the datepickertextbox. I had to include WPFToolkit for the maskedtextbox control. Then, I created a new class that inherits from Datepicker and added a few dependencyproperties. From there I created a resourcedictionary for the XAML of how to display this new custom date picker. You can build You'll lose the watermark but you gain a mask which I think is more user friendly.
You won't be able to accomplish what you are looking for without a custom control since Datepicker is tightly synced together where the selected Calendar date is an actual date and SelectedDate has to also be a date and the format MMDDYYYY isn't considered a date.
I managed to accomplish that easily with telerik's RadDatePicker. Setting AllowParsingWithoutSeparator="True" property resolved my issue. The other solution is to have a textbox with mask.

Approaches to WPF binding validation?

I'm struggling to find a satisfactory approach to data validation in WPF/MVVM. I've been using IDataErrorInfo but if I bind a textbox to (say) an int property, and enter a non-numeric value, WPF generates its own validation message ("value 'xyz' could not be converted"). The control does get highlighted as being in error, but my viewmodel is unaware that the property is in an invalid state, as the binding (and therefore the IDataErrorInfo validation) never happened.
I haven't looked into custom validators yet. Using these is it possible to notify the view model that there are errors? I'm a bit reluctant to use them as it seems excessive to create validator classes for each of the many rules that a complex application requires. Maybe I could use a mixture of the two approaches, i.e. a basic custom validator that ensures that the input is numeric, and IDataErrorInfo for the more complex stuff?
I'm also struggling to validate "related" properties using IDataErrorInfo. Say my model has "Min" and "Max" properties and I want to ensure that Min is less than Max. If I change the "Min" textbox to be greater than Max, the control would be correctly marked as invalid. If I now change "Max" to be greater than "Min", the "Min" textbox validation state does not get cleared down (presumably because "Min" hasn't changed and therefore doesn't get validated again). What's the best approach for this situation?
I would be interested to know how others have tackled WPF validation. Are there any improvements to WPF validation in .Net 4.5?
Suspect you are aware of this but set never even gets called if the type does not match (or cannot be converted).
Had this problem with an empty TextBox bound to an Int? as the TextBox was passing String.Empty not null. So used a converter to convert String.Empty to null.
A TextBox is going to accept text. There is no getting around that.
You can bind to string so everything gets through to the set.
Or you can handle the keydown event at the UI and only allow numeric and bind to Int. Then in the validation determine if the value is in range.

Auto complete feature for DatePicker in Silverlight

I am building a silverlight 4 application and the user wants to have a autocompelte feature for
date controls. ( Note I am using the DatePicker). For e.g. when the user types 5 and tabs out
the date should be converted to 5'th of sept 2012 becuase 5'th august has gone past. I also have
some other rules that are in place for this date formation. I planned to write some code
for this one in the KeyUp event but I am unable to get the text that the user has entered in the
datepicker. Also TextInputStart and TextInputUpdate are never called in my case.
I am looking for the correct event in which I can get what the user has entered
Thanks
Amol
I had a similar problem once with the DatePicker of the Silverlight Toolkit. The only way I could solve that was to create a new UserControl using a standard TextBox and a DatePicker. I re-styled the DatePicker so that its default text area remained hidden, and replaced it by the standard TextBox.
I wired the DatePicker's SelectedDate-Property to the Text-Property of the TextBox, so that it would get updated once someone picks a date.
In your case you could use the AutoCompleteBox coming with the Toolkit instead of a standard TextBox and then use some clever logic to prefill the list of auto-complete proposals. Thus your control would look like a standard DatePicker, and mostly behave like one, but would provide a mixed functionality of DatePicker, TextBox and AutoCompleteBox.

Data binding: Different triggers for different purposes

I have a WPF MVVM data form window with data validation. A lot of the controls are text boxes. Currently, the data binding trigger is set to the default, i. e. loss of focus. This means that a field is only validated when it is likely to be filled out completely. So when deleting a number and typing another number, the transient empty value will not be displayed as input error.
But a drawback is that the Save button can only be enabled when the focus moves out of the text box. (No matter where, just out of the edited control. Assuming there is anything else focusable.) If this is the only change, the user waits for the Save button to be available and nothing happens. For the Save button, I'd like to use an immediate binding trigger. How can that be done?
Edit: Forgot to mention that my Save button (which uses ICommand) is only enabled when the input is determined modified and valid. So the data will remain unmodified until data binding updates it, and that won't happen until the focus moves to another control.
I actually had a similar question a while back and the solution I ended using was a custom DependencyProperty that kicked off a timer when a key was pressed, and only actually processed the PropertyChange notification if a specific time had passed.
This means the bound property doesn't get updated (and validated) unless the user pauses in typing for a set period of times.
The code can be found here (may need a bit of cleanup), and it is used like this:
<TextBox
local:DelayedUpdateBehavior.TargetProperty="{x:Static TextBox.TextProperty}"
local:DelayedUpdateBehavior.Milliseconds="1000"
Text="{Binding MyTextProperty, UpdateSourceTrigger=Explicit}" />
Edit: Actually this link might be better. It's a markup extension so you can use it directly from your binding. I can't remember which of these two methods I used in the past, but I know it was one of them :)
<TextBox Text="{local:DelayBinding Path=MyTextProperty, Delay='00:00:01'}" />
Assuming you're using an ICommand type interface for the button click event:
You can...Implement string properties with INotifyPropertyChanged and bind them to your textbox controls. Now in your Command canexecute method you can check to see if the property is !nullorempty.
e/ grammar
Set your Binding's UpdateSourceTrigger property to PropertyChanged. The default for TextBoxes is LostFocus.
Update: So you want to have data binding working on your TextBox and only allow numbers? Have a look at this question: Create WPF TextBox that accepts only numbers
Or use a converter and bind the Save button's IsEnabled property to your TextBox (maybe using a MultiBinding if there's more than one), and use a converter which determines if the text is a valid number and returns true or false.

WPF Binding to a non-changing property

I'm using the MVVM pattern and I have a POCO (in my Model) with a Start Date property.
I want to show the elapsed time since the start date in a control on a WPF window/user control...
I don't see how I can bind a ModelView property to a UI control and have it update this duration automatically...can anyone suggest a way?
I could use something (a timer or a thread) to update a duration property on my ModelView but I just don't see any other way because as I understand it the UI will only update when a property value changes. However the start date on my POCO isn't changing it's just the elapsed time that's changing which is a calculated value.
Am I missing something?
You're on the right track. Have a look at the Presentation Model pattern on Martin Fowler's page.
The basic idea is to build a model for the UI (ViewModel) and have the UI just sync up with it. Every bit of information to be displayed in the UI, should have a corresponding field or property in the ViewModel (although they may be retrieved or derived from values in the Model) .. the ViewModel makes it easy to store the View State/Session State (such as the current selection of items in a UserList) which is not present the in the Model class behind.
Since you want to show the 'elapsed time since' value in the UI, your ViewModel should have a property caled ElapsedTimeSince. Your WPF View has a control which is data-bound to this property.
Now as per your need, ensure you have a thread/timer event that re-evaluates the property value periodically using the current time and the Model's StartDate property. Your UI should reflect the updated value.

Resources