Ramakant Yadav the Internet edition

The curious case of the textbox that would not update

29 December 2012



So here is my scenario: You have a MVVM based WPF project. The view Model is all set up, the database is good to go. Since you are using MVVM, you decide to use dependency properties to bind the textbox with the string in your view model. Oh, and there is one small requirement, you want to restrict the textsize to 10 characters. Something like this:

 public class ViewModelSample :ViewModel
    {
        #region "Properties"
        private int _id;
        public int ID
        {
            get { return _id; }
            set
            {
                _id = value;
                if (_id == 0)
                {
                    Name =String.Empty;
                }
                OnPropertyChanged("id");
            }
        }
 
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                if (value.Length > 10)
                {
                    //THIS WILL NOT WORK.
                }   
                else { _name = value; }
                
                OnPropertyChanged("Name");
            }
        }
 
        #endregion
 
        #region Constructor
        public ViewModelSample()
        {
            this.ID = 123;
            this.Name = "abc";
        }
        #endregion
 
 
    }
   

In the viewmodel above, notice the Name Property. It is supposed to prevent the user from entering more than 10 characters. Sounds good so far. The XAML looks like the following:

<Window x:Class="DemoApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:DemoApplication"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:ViewModelSample></vm:ViewModelSample>
    </Window.DataContext>
    <Grid>
        <TextBox Text="{Binding Path=ID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="188,51,97,239" />
        <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="188,81,97,208" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="102,52,0,0" Name="textBlock1" Text="ID" VerticalAlignment="Top" Width="80" FlowDirection="RightToLeft" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="102,80,0,0" Name="textBlock2" Text="Name" VerticalAlignment="Top" Width="80" FlowDirection="RightToLeft" />
    </Grid>
</Window>

The Name property of the view model is bound to the text property of the second textbox. Nothing fancy.  

You would think that the when  the application is run, the viewmodel would not accept more than 10 characters. That thought would be absolutely valid, the viewmodel would work as expected and the Name property would never have more than 10 characters. But the textbox would easily continue to display as many characters as the user typed in.  So the user would get no cue to stop entering characters, unless, of course, we put in some code to inform the user otherwise. [Of course you could put in MaxLength]

This in my opinion is a major bug that can lead to a few hours of head scratching that will lead to nowhere. Microsoft has fixed this bug in Framework 4.5 by introducing a new property FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty , so if you or your clients need your application to work in framework 4.0 or on Windows XP, then you will have to look for something else.

Just for extra fun, this will update your textbox just fine::

 public string Name
        {
            get { return _name; }
            set
            {
                if (value.Length > 5)
                {
                    //THIS WILL  WORK.
                    _name = String.Empty;
                }   
                else { _name = value; }
                
                OnPropertyChanged("Name");
            }
        }

That is not all, did you know that there is no masked textbox control in WPF? Yes, if you want a masked textbox, then you need to get busy writing your own custom control. Good luck with that.

So in the end  WPF  with MVVM in version 4.0 has issues that may cause hiccups when coding a line of business application. The textbox's text property is one of them. I wish someone had told me before about this bug before, hopefully this will help someone else out there.

* All trademarks belong to their respective owners.


The Archives | comments@ramakantyadav.com | Home

All Rights Reserved ramakantyadav.com