Timepicker Updatesourcetrigger=propertychanged doesn't change value - wpf

I'm hosting a WPF usercontrol in a windows form
In the wpf user control I am using a timepicker from wpfToolkit.extended
If I use the up or downkeys or just enter a time in the textfield the source is not updated allthough I am using Updatesourcetrigger = propertychanged.
When I select a time in the dropdrownlist everything works the way it should.
This is the namespace of the toolkit.
xmlns:xctk="clr-namespace:Xceed.Wpf.Toolkit;assembly=WPFToolkit.Extended"
This is the xaml for the timepicker
<xctk:TimePicker Format="LongTime" TimeInterval="00:15:00.000" Value="{Binding Path=StartTime, UpdateSourceTrigger=PropertyChanged}" ></xctk:TimePicker>
If I click outside the WPFusercontrol without changing the focus to another control in the wpf usercontrol first. The Binded time is not updated.
Any idea how I can fix this?

Found a solution for this problem:
I've given the TimePicker a name (In this case 'tpFrom') then I've used the TextBoxBase.TextChanged event on the TimePicker.
This is what the Xaml looks like now:
<xctk:TimePicker Name="tpFrom" Format="LongTime" TextBoxBase.TextChanged="TimePicker_TextChanged" TimeInterval="00:15:00.000" Value="{Binding Path=StartTime, UpdateSourceTrigger=PropertyChanged}"></xctk:TimePicker>
In the code behind in our eventhandler we'll put the focus on our timepicker.
private void TimePicker_TextChanged(object sender, TextChangedEventArgs e)
{
tpFrom.Focus();
}
Now everytime the text changes, the value changes as well and the problem is solved :-)

Does the TimePicker have a Text property? If so, try binding to that instead.
I think this behavior might be to prevent you from binding to a bad datetime as you type. I would guess that when focus is lost it tries to set the property and does error checking. If it did this while you typed it would constantly be changing the value anytime you make a change (say delete a character).
Is there something specific you are trying to do as you type?

Related

StringFormat, TextBox Validation and Caret Position

I'm having an issue I need to work around. The caret position of my TextBox is reset to the first character when certain events happen. Here's the XAML for my TextBox, my application is using MVVM:
<TextBox x:Name="txtAmount" Text="{Binding CurrentClientObject.Amount, Mode=TwoWay, StringFormat='###,###,##0.00'}"></TextBox>
Is bound to model property:
private System.Nullable<decimal> _Amount;
[Display(ResourceType = typeof(MatchModelResx), Name = "LabelAmount", Description = "ToolTipAmount")]
public System.Nullable<decimal> Amount
{
get
{
return _Amount;
}
set
{
_Amount = value;
NotifyChanged("Amount");
}
}
The StringFormat is causing the issue here, since whenever the string I input in the TextBox triggers a refresh of the property in the model, the StringFormat is applied and the caret inside the TextBox moves
Now this wouldn't be a problem, since the model is refreshed on the lostfocus (UpdateSourceTrigger = Default), but there is a case when the TextBox is in Error mode. If the user either enters a value that breaks a custom validation rule, or is in the invalid format (i.e: enters 64.5x5 in a field bound to a decimal), every single keychange triggers a refresh of the property in the model. And since a model refresh may cause the StringFormat to be applied, this means the caret will move to the left while a user is trying to correct an invalid value in the TextBox. This is an irritating behaviour for our customers, and we really need to find a way around it.
I've tried using a custom converter on the binding instead of a stringformat, but that's not fixing the issue. And since the exception is sometimes raised before the code reaches the property Set, I have no way to handle this before the caret moves.
Does Silverlight 5 offer a way to work around this?
Thanks!
Not sure if you have set the UpdateSourceTrigger=PropertyChanged, for textbox this causes the refresh everytime you press the Key and StringFormat is applied, to fix this it should be set to "Default" which is LostFocus
http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger(v=vs.110).aspx

Ignoring text/value changes due to databinding

How does one ignore changes to a control when databinding occurs? I tried hooking various events like gotfocus,textchanged,and leavefocus, but if the control already has focus and the user "cancels" their changes, when I reload the record and data binding takes over, textchanged thinks the user still made the change since the focus is on that control. The call stack is empty. Are there any global data binding events like databinding starting and databinding ending? I see where I fire my OnProperyChanged but within that call, databinding does not occur. Looks like it's getting "queued" up and runs at some other point.
At one point, I was going to hook the property change events in our view model , but this means I won't detect and can't VISUALLY display the form is modified till the user leaves the control. I know, I know, I can change all my bindings so that binding occurs immediately on every character change but then this messes with some validation cases as the user hasn't finished typing in their value.
I'd really love some kind of event like TextChangedByUser that would fire whether the user used a key, clipboard, mouse clipboard, anything triggered by the user.
I just can't figure out how to distinguish between user changes and databinding changes.
I'd really love some kind of event like TextChangedByUser that would
fire whether the user used a key, clipboard, mouse clipboard, anything
triggered by the user.
I just can't figure out how to distinguish between user changes and
databinding changes.
Don't use the Text.TextChanged event to detect user input,
use the Binding.SourceUpdated event instead.
Or more general:
Don't use the DPs of your visual elements to detect user updates, use the Binding.SourceUpdated event instead.
This is a RoutedEvent.
At your binding, you have to set NotifyOnSourceUpdated = true. With help of UpdateSourceTrigger you are even able to finetune when you want to be informed.
Your xaml could be sth like this:
<Grid x:Name="LayoutRoot" Binding.SourceUpdated="LayoutRoot_SourceUpdated">
...
<TextBox>
<TextBox.Text>
<Binding NotifyOnSourceUpdated="True" Path="path" UpdateSourceTrigger="PropertyChanged" >
</Binding>
</TextBox.Text>
</Grid>
Your event could be like this:
private void LayoutRoot_SourceUpdated(object sender, DataTransferEventArgs e)
{
// called every time s.th. changed by user
}
(edited due to comment)
Why is this a valid way to detect if an input is triggered in any way by the user?
In the given example, the TextBox's DataContext 'path' property is the source, while the 'TextBox.Text' property is the target.
[Data Binding Overview]http://msdn.microsoft.com/en-us/library/ms752347.aspx
The TextBox.Text property is changed for the first time when the binding initializes and the source-value is written to the 'TextBox.Text' property. Because you do not know when the binding takes place exactly you cannot use the TextBox.Text property or any of its events (e.g. TextChanged) to detect a user input. Hence:
Don't use the Text.TextChanged event to detect user input!!! more general: Don't use the DPs of your visual elements to detect user updates!!!
If the user changes the content of the visual text field by which means whatsoever, the 'TextBox.Text' property changes (your target).After that, the binding updates the source at a time defined by UpdateSourceTrigger.That's when the SourceUpdated event is fired.
I admit not to know the effect of changes to the binding source from outside the binding.
But I have a complete Editor-like Desktop-Application detecting changes by the user that way and it is working very nicely.
You should update your Binding Code to set the following
{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
EDIT: Sorry, I have overseen the fact that you already know this...In that case, I can't help :(
You can use the UIElement.TextInput event to detect user input.
Note that the event is probably already handled by the input control itself so you might have to use the UIElement.PreviewTextInput event.

Why won't my WPF bound Visibility property update?

I have a textblock in my XAML where the Visibility is bound to a property in my viewmodel. When the window first loads, the value from the viewmodel determines the visibility correctly (I tried manually overriding the backing store variable value and it works great, hiding the control as I need). However, when I change the property value the visibility doesn't change.
Here's the XAML for the control:
<TextBlock Text="Click the button" Style="{StaticResource Message}" Visibility="{Binding NoResultsMessageVisibility}" />
The "NoResultsMessageVisibility" property that I bind to is this:
public Visibility NoResultsMessageVisibility
{
get { return _noResultsMessageVisibility; }
set
{
_noResultsMessageVisibility = value;
NotifyPropertyChanged("NoResultsMessageVisibility");
}
}
NotifyPropertyChange raises a PropertyChanged event for the provided name using standard INotifyPropertyChanged.
Can anyone spot my mistake?
EDIT
In response to the comments / answer so far.
The program is super simple so there's no parallelism / multithreading used.
The DataContext is set only once when the window loads, using:
new MainWindow { DataContext = new MainWindowViewModel() }.ShowDialog();
The binding does seem to work when first loaded. I've noticed as well that a textbox I have bound to a property isn't updating when I change the property. However, the property is definitely updating when I change the textbox as the value is used as the basis for a command that's bound to a button. As the text changes, the button is enabled and disabled correctly and when I click it the value from the property is correct. Again, if I set a value against the backing store variable, this shows in the textbox when the window first loads.
Don't see anything wrong with this, is it possible that the DataContext gets changed, so the binding breaks? (You only specify the path, so it's relative to the current DataContext)
Solved it. I'm a dozy dork :)
I have copied some code from another class and for some reason I'd added the PropertyChanged event to my viewmodel's interface, rather than implementing INotifyPropertyChanged on the interface. D'Oh!

wpf: TextChanged event fired on setting DataContext

I've got a simple View with a single textbox that gets databound to a simple ViewModel with a single string property.
I need to catch the TextChanged event of that textbox so that I can do a little validation magic.
The problem that I am running into is that the TextChanged event fires for that textbox when the DataContext is set for the View.
Is there a standard mechanism that I can use to determine if the event is firing because of the DataContext being set versus when the user is making changes?
Thanks!
As far as I know there is no such mechanism. What you should do instead is to do your validation magic using standard means of WPF. Please see the following link: http://msdn.microsoft.com/en-us/library/ms752347.aspx#data_validation.
Anyway, as long as you use MVVM you can always detect that text has changed in the setter of the bound property in your view model.

TextBox.TextChanged & ICommandSource

I am following the M-V-VM pattern for my WPF UI. I would like to hook up a command to the TextChanged event of a TextBox to a command that is in my ViewModel class. The only way I can conceive of completing this task is to inherit from the TextBox control, and implement ICommandSource. I can then instruct the command to be fired from the TextChanged event. This seems to be too much work for something which appears to be so simple.
Is there an easier way (than subclassing the TextBox and implementing ICommandSource) to hook up the TextChanged event to my ViewModel class?
First off, you've surely considered two-way data binding to your viewmodel, with an UpdateSourceTrigger of PropertyChanged? That way the property setter of the property you bind to will be called every time the text is changed?
If that's not enough, then I would tackle this problem using Attached Behaviours. On Julian Dominguez’s Blog you'll find an article about how to do something very similar in Silverlight, which should be easily adaptable to WPF.
Basically, in a static class (called, say TextBoxBehaviours) you define an Attached Property called (perhaps) TextChangedCommand of type ICommand. Hook up an OnPropertyChanged handler for that property, and within the handler, check that the property is being set on a TextBox; if it is, add a handler to the TextChanged event on the textbox that will call the command specified in the property.
Then, assuming your viewmodel has been assigned to the DataContext of your View, you would use it like:
<TextBox
x:Name="MyTextBox"
TextBoxBehaviours.TextChangedCommand="{Binding ViewModelTextChangedCommand}" />
Using the event binding and command method might not be the right thing to use.
What exactly will this command do?
You might want to consider using a Databinding to a string field in your VM. This way you can make a call to a command or function from there rather than having the UI care at all.
<TextBox Text="{Binding WorldName}"/>
....
public string WorldName
{
get
{
return WorldData.Name;
}
set
{
WorldData.Name = value;
OnPropertyChanged("WorldName");
// CallYourCustomFunctionHere();
}
}
Can you not just handle the TextChanged event and execute the command from there?
private void _textBox_TextChanged(object sender, EventArgs e)
{
MyCommand.Execute(null);
}
The alternative, as you say, is to create a TextBox that acts as a command source, but that does seem like overkill unless it's something you're planning on sharing and leveraging in many places.

Resources