Textbox updates itself while typing - c#

I have the following textbox binded to a MVVM ViewModel
Textbox
<TextBox Height="71" Width="341"
Text="{Binding BalanceValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, StringFormat=N2}"
Margin="0,2,2,2" HorizontalAlignment="Right"/>
Below is my ImportPresenter Which handles the input.
Public Class ImportPresenter : ObservableObject
{
private double _BalanceValue = 0;
public double BalanceValue
{
get
{
return _BalanceValue;
}
set
{
_BalanceValue = double.Parse(value.ToString(),
System.Globalization.NumberStyles.Currency);
RaisePropertyChangedEvent("BalanceValue");
}
}//END BALANCEVALUE
}
For the most part, this works, except when testing, The TextBox is updating itself while I'm typing. Should I use a different event for the TextBox?

in some situations updating viewmodel on LostFocus and on every PropertyChanged is equally inconvenient. (e.g. typing key word for search - we don't want to run search after each letter, we want to do it when users stop typing - but they don't leave search field)
since .net 4.5 Binding class has Delay property (in milliseconds):
Text="{Binding BalanceValue, Mode=TwoWay, Delay=333, UpdateSourceTrigger=PropertyChanged, StringFormat=N2}"
To avoid updating the source object with every keystroke, set the Delay property to a reasonable value to cause the binding to update only after that amount of time has elapsed since the user stopped typing.

By default, the UpdateSourceTrigger for the TextBox is Lost Focus. By setting it to PropertyChanged it will update for every change made, e.g. every character.

Related

WPF How do I stop MaskedTextBox from clearing text when I click on it

This is the xaml of my MaskedTextBox(from Extended WPF Toolkit) which I bind the text with property Time in my datacontext.
<wpfx:MaskedTextBox
x:Name="MyMaskedTextBox"
AllowPromptAsInput="True"
Mask="00:00:00"
PromptChar="0"
ResetOnPrompt="False"
Text="{Binding Time, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
This is the part of my Datacontext that updates it, and my Time property.
public class MyViewModel : ObservableObject, INavigationAware {
public string Time {
get;
set; //break point 1
}
public static void UpdateTime(string time) {
Time = time;
OnPropertyChanged("Time");
}
}
The problem is whenever I click on the MaskedTextBox, the text reverts back to the prompt character.
For example I would start up the app and the MaskedTextBox would have 00:00:00. After some event, I update the time property to 12:34:56, and it would correctly show on the UI. But when I click on the MaskedTextBox, it changes the text back to 00:00:00.
Break point 1's call stack just shows "external code". I couldn't find an option in the document to turn this behavior off, how do I stop it?
Try to bind the Value property to your Time property instead of binding the Text property:
<wpfx:MaskedTextBox
...
Value="{Binding Time, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
The control itself sets the Text property based on the Value and the Mask.

TextBlock binding to user property displays empty text

I've bound many things without issue, but this one isn't working for some reason. I have a base viewmodel that loads a property called User from the login window:
public void LoadUser()
{
if ((LoginState?)Application.Current.Properties["LoginState"] == LoginState.Success)
{
User = new UserModel((string)Application.Current.Properties["UserLName"], (string)Application.Current.Properties["UserFName"], (int)Application.Current.Properties["UserLevel"]);
RaisePropertyChanged("User");
}
}
This part works fine according to the breakpoint values. This property User is in the base of the viewmodel that is attached as the DataContext of my MainWindow. I bind it on the view with this:
<TextBlock Text="{Binding Path=Name, Source=User}"
Grid.Column="1" Grid.Row="1" Foreground="Black"/>
I know the text block works as I can bind other properties to it, but it won't display this property for some reason. Can you see why?
TextBlock's Default Binding MAY not be TwoWay. So Can you Set it to be TwoWay explicitly in xaml and check once.
Also, that RaisePropertyChanged is custom implementation right. Can you step into it during debug and see if the Event is Null?

Textbox - bound property value does not update immediately

I have a textbox which is bound to a property ItemID like so.
private string _itemID;
public string ItemID {
get { return _itemID; }
set {
_itemID = value;
}
}
The XAML of the text box is as follows:
<TextBox Text="{Binding Path=ItemID, Mode=TwoWay}" Name="txtItemID" />
The problem is, the value of ItemID does not update immediately as I type,
causing the Add button to be disabled (command), until I lose focus of the text box by pressing the tab key.
Yes, by default, the property would be updated only on lost focus. This is to improve performance by avoiding the update of bound property on every keystroke. You should use UpdateSourceTrigger=PropertyChanged.
Try this:
<TextBox
Text="{Binding Path=ItemID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Name="txtItemID" />
You should also implement the INotifyPropertyChanged interface for your ViewModel. Else, if the property is changed in the ViewModel, the UI would not get to know about it. Hence it would not be updated. This might help in implementation.
You need to fire the OnPropertyChanged event in the setter, otherwise the framework has no way of knowing that you edited the property.
Here are some examples:
Implementing NotifyPropertyChanged without magic strings
Notify PropertyChanged after object update

WPF TwoWay not working on X (exit) but works on TAB or clicking elsewhere

I have the following in my XAML:
<TextBox Name="TitleValue"
Text="{Binding ElementName=ListValue, Path=SelectedItem.Title, Mode=TwoWay}"
<TextBox Name="DescValue"
Text="{Binding ElementName=ListValue,
Path=SelectedItem.Description, Mode=TwoWay}"
When I enter a value in either TitleValue or DescValue and Tab or click on a different location in the window, the collection class properties are updated correctly. Then when I click the X to exit the window, the data in the collection class is saved correctly.
However, when I enter a value in either of those fields, then click X to exit the window, the data in the collection class is saved, but the value entered is not saved for that particular field I was editing when I clicked X.
I implemented a lose focus event on the fields and they work, even when the X is clicked. In those events I put the code:
private void Event_DescValue_LoseFocus(object sender, RoutedEventArgs e)
{
((Import)ListValue.SelectedItem).Description = ((TextBox)e.OriginalSource).Text;
}
But that didn't work either. the following does not work either:
Imports[ListValue.SelectedIndex].Description = ((TextBox)e.OriginalSource).Text;
How do I get the collection class Imports to update the selected class Import when X is clicked when in a field being edited?
It should work exactly like I had Tabbed off the field being edited or clicking elsewhere in the window.
Modify your binding's UpdateSourceTrigger to PropertyChanged.
Like so:
<TextBox Name="TitleValue" Text="{Binding ElementName=ListValue,
Path=SelectedItem.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

Can't click textbox after validation fails

I'm working on trying to implement validation in WPF, and running into an issue where I can't click on or change the value of a textbox after validation fails.
I have a User class (which implements IDataErrorInfo), which contains the following relevant code:
public virtual string Error
{
get
{
return null;
}
}
public virtual string this[string name]
{
get
{
string result = null;
if (name == "uFirstName")
{
if (String.IsNullOrEmpty(this.uFirstName))
{
return "Must enter a first name!";
}
}
return result;
}
}
Then, over in my MainWindow code-behind, I have this code to hookup my combobox:
comboBox1.ItemsSource = Users; //Users is a collection of Users
Finally, in my MainWindow xaml, I have this:
<ComboBox Name="comboBox1" ItemTemplate="{StaticResource userTemplate}" />
<TextBox Name="textBox1" DataContext="{Binding ElementName=comboBox1,
Path=SelectedItem}" Text="{Binding Path=uFirstName, ValidatesOnDataErrors=True,
NotifyOnValidationError=True}"/>
And indeed, the validation does fire when I delete the text and the textbox gets a nice red border. However, the changes are still sent back to Users (uFirstName gets set to nothing!). Even worse though, I now cannot edit the value in that textbox unless I tab back into it.
What is needed to make sure the value isn't sent back if it isn't valid, and allow the textbox to be edited if is invalid?
The IDataErrorInfo implementation is only there to report errors. You should implement your verification in the uFirstName property. If you don't think a certain verification on a property is true for all instances, you should start looking into ValidationRule. This is a better way of implementing Validation in WPF. ValidationRule will not set value to the source, if the validation fails.
The textbox might be acting strange because of a system level style? Not exactly sure on why you are having trouble there.

Categories