Same case as this previous post link but different implementation.
Because I have around 10 textboxes, and I think is it not good to create a lots of lost focus command in view model, plus this reset to default value when lost focus is one of the requirements. If I need to implement property changed with icon notification
then my view model will be very messy and complex.
Anyone else have better suggestions ?
Download Project
How to implement the textbox will get back to the default value when textbox in lost focus by using attached behavior ?
E.g
Any changes that has been done by user on textbox A, if he/she does not press the enter key and lost focus to another text box B. The textbox A value will change back to the default value.
If the user has press the enter key, the default value will be replaced by changes that has been done by user.
MainWindow XAML
<Window x:Class="TestValidationRule.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vr="clr-namespace:TestValidationRule" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:WPFBehaviorsSample="clr-namespace:TestValidationRule" Title="MainWindow" Height="350" Width="525"><Window.Resources><Style x:Key="TextBoxErrorStyle" TargetType="TextBox"><Style.Triggers><Trigger Property="Validation.HasError" Value="True"><Setter Property="Foreground" Value="Red" /></Trigger></Style.Triggers></Style></Window.Resources><StackPanel Orientation="Horizontal"><TextBox x:Name="txtDiagPeriod" Width="150" Height="30" Validation.ErrorTemplate="{x:Null}" Style="{StaticResource TextBoxErrorStyle}"><TextBox.Text><Binding Path="DiagPeriod" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"><Binding.ValidationRules><vr:DiagPeriodValidationRule x:Name="DiagPeriodValidation" /></Binding.ValidationRules></Binding></TextBox.Text><TextBox.InputBindings><KeyBinding Key="Enter" Command="{Binding WriteDiagPeriodCommand}" CommandParameter="{Binding ElementName=txtDiagPeriod, Path=(Validation.HasError)}"></KeyBinding></TextBox.InputBindings><i:Interaction.Behaviors><WPFBehaviorsSample:ShowMessageOnLostFocusBehavior /></i:Interaction.Behaviors></TextBox><TextBox Width="150" Height="30" /></StackPanel></Window>
MainWindow View Model
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows; using System.Windows.Input; namespace TestValidationRule { public class MainWindowViewModel : INotifyPropertyChanged { private uint diagPeriod; public uint DiagPeriod { get { return diagPeriod; } set { diagPeriod = value; OnPropertyChanged("DiagPeriod"); } } private ICommand writeDiagPeriodCommand; public ICommand WriteDiagPeriodCommand { get { return writeDiagPeriodCommand; } set { writeDiagPeriodCommand = value; } } private uint defaultDiagPeriod = 100; public MainWindowViewModel() { writeDiagPeriodCommand = new RelayCommand(ExecuteWriteDiagPeriodCommand); //initial when first launch diagPeriod = defaultDiagPeriod; } public void ExecuteWriteDiagPeriodCommand(object parameter) { var IsDiagPeriodHasError = (bool)parameter; if (!IsDiagPeriodHasError && defaultDiagPeriod != diagPeriod) { defaultDiagPeriod = diagPeriod; MessageBox.Show("Hello: " + defaultDiagPeriod); } else { } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string name) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(name)); } } } }
Lost Focus Behaviour
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Interactivity; namespace TestValidationRule { public class ShowMessageOnLostFocusBehavior : Behavior<TextBox> { protected override void OnAttached() { AssociatedObject.LostFocus += AssociatedObjectOnLostFocus; base.OnAttached(); } protected override void OnDetaching() { AssociatedObject.LostFocus -= AssociatedObjectOnLostFocus; base.OnDetaching(); } private void AssociatedObjectOnLostFocus(object sender, RoutedEventArgs routedEventArgs) { MessageBox.Show(AssociatedObject.Text); } } }