Click here to Skip to main content
15,887,485 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have two TextBoxes inside my View on which I am trying to implement a simple validation using MVVM design pattern.The issue is even when my ViewModel is implementing Inotification Changed interface and the property is bound tot the text property of the TextBox,on entering text propertyChange event never fires.I don't know where I have gone wrong.Please help.Its been bugging me for quite a while.

ViewModel :

 

     class TextBoxValidationViewModel : ViewModelBase, IDataErrorInfo
        {
            private readonly TextBoxValidationModel _textbxValModel;
            private Dictionary<string, bool> validProperties;
            private bool allPropertiesValid = false;
    
            private DelegateCommand exitCommand;
            private DelegateCommand saveCommand;
    
            public TextBoxValidationViewModel(TextBoxValidationModel newTextBoxValObj)
             {
                this._textbxValModel = newTextBoxValObj;
                this.validProperties = new Dictionary<string, bool>();
                this.validProperties.Add("BuyTh", false);
                this.validProperties.Add("SellTh", false);
                
    
            }
    
    
            public string BuyTh
            {
                get { return _textbxValModel.BuyTh; }
                set
                {
                    if (_textbxValModel.BuyTh != value)
                    {
                        _textbxValModel.BuyTh = value;
                        base.OnPropertyChanged("BuyTh");
                    }
                }
            }
    
            public string SellTh
            {
                get { return _textbxValModel.SellTh; }
                set
                {
                    if (_textbxValModel.SellTh != value)
                    {
                        _textbxValModel.SellTh = value;
                        base.OnPropertyChanged("SellTh");
                    }
                }
            }
    
    
    
            public bool AllPropertiesValid
            {
                get { return allPropertiesValid; }
                set
                {
                    if (allPropertiesValid != value)
                    {
                        allPropertiesValid = value;
                        base.OnPropertyChanged("AllPropertiesValid");
                    }
                }
            }
    
    
            public string this[string propertyName]
            {
                get
                {
                    string error = (_textbxValModel as IDataErrorInfo)[propertyName];
                    validProperties[propertyName] = String.IsNullOrEmpty(error) ? true : false;
                    ValidateProperties();
                    CommandManager.InvalidateRequerySuggested();
                    return error;
                }
            }
    
            public string Error
            {
                get
                {
                    return (_textbxValModel as IDataErrorInfo).Error; 
                }
            }
    
            public ICommand ExitCommand
            {
                get
                {
                    if (exitCommand == null)
                    {
                        exitCommand = new DelegateCommand(Exit);
                    }
                    return exitCommand;
                }
            }
    
            public ICommand SaveCommand
            {
                get
                {
                    if (saveCommand == null)
                    {
                        saveCommand = new DelegateCommand(Save);
                    }
                    return saveCommand;
                }
            }
    
    
    
            #region private helpers
    
            private void ValidateProperties()
            {
                foreach (bool isValid in validProperties.Values)
                {
                    if (!isValid)
                    {
                        this.AllPropertiesValid = false;
                        return;
                    }
                }
                this.AllPropertiesValid = true;
            }
    
            private void Exit()
            {
                Application.Current.Shutdown();
            }
    
    
            private void Save()
            {
                _textbxValModel.Save();
            }
    
        }
    
    }
    #endregion


Model :
=========

      class TextBoxValidationModel : IDataErrorInfo
        {
    
            public string BuyTh { get; set; }
            public string SellTh { get; set; }
    
            public void Save()
            {
                //Insert code to save new Product to database etc 
            }
    
            public string this[string propertyName]
            {
                get
                {
                    string validationResult = null;
                    switch (propertyName)
                    {
                        case "BuyTh":
                            validationResult = ValidateName();
                            break;
                        case "SellTh":
                            validationResult = ValidateName();
                            break;
                       
                        default:
                            throw new ApplicationException("Unknown Property being validated on Product.");
                    }
                    return validationResult;
                }
            }
    
            public string Error
            {
                get
                {
                    throw new NotImplementedException();
                }
            }
    
    
            private string ValidateName()
            {
    
                return "Entered in validation Function";
            }
        }
    }

ViewModelBase abstract Class :

     public abstract class ViewModelBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
    
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }

Application Start event code:
===============================
       private void Application_Startup(object sender, StartupEventArgs e)
            {
                textboxvalwpf.Model.TextBoxValidationModel newTextBoxValObj = new Model.TextBoxValidationModel();
                TextBoxValidation _txtBoxValView = new TextBoxValidation();
                _txtBoxValView.DataContext = new textboxvalwpf.ViewModel.TextBoxValidationViewModel(newTextBoxValObj);
          //      _txtBoxValView.Show();
    
            }
        }


View Xaml code:
==================


    <Window x:Class="textboxvalwpf.TextBoxValidation"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:c="clr-namespace:textboxvalwpf.Commands"
            xmlns:local="clr-namespace:textboxvalwpf"
            mc:Ignorable="d"
            Title="TextBoxValidation" Height="300" Width="300">
        <Grid>
            <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="86,44,0,0" TextWrapping="Wrap" Text="{Binding Path=BuyTh, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
            <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="88,121,0,0" TextWrapping="Wrap" Text="{Binding Path=SellTh,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
            <Label x:Name="label_BuyTh" Content="Buy Th" HorizontalAlignment="Left" Margin="10,44,0,0" VerticalAlignment="Top" Width="71"/>
            <Label x:Name="label_SellTh" Content="Sell Th" HorizontalAlignment="Left" Margin="10,117,0,0" VerticalAlignment="Top" Width="71"/>
    
        </Grid>
    </Window>


What I have tried:

I tried to search in the internet and couldn't find anything like that.This is a very simple this and I am getting irritated going around this.
Posted
Updated 18-Jan-17 7:22am

1 solution

Have you put a breakpoint in your setter to see if that is even being fired? Check that and also change your binding path to TwoWay binding to see if that is the issue.

<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="86,44,0,0" TextWrapping="Wrap" Text="{Binding Path=BuyTh, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>


WPF binding is extremely fickle. IDataErrorInfo is also a bit of a pain for client side validation.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900