0

My Xaml

<TextBox Text="{Binding MyVal, Mode=TwoWay}" ></TextBox>

My Viewmodel

private string myVar;

    public string MyVal
    {
        get
        {
            return myVar;
        }
        set
        {
            if (value.Length > 6)
                myVar = value;
            else
                myVar = "Not a valid INPUT";
            OnPropertyChanged("MyVal");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

when ever user enters a less than 6 char string the textbox should disply error message. instead of that the textbox text is remains same as the user input. But the variable value is changing as expected.

I'm using WinRT app please help Thanks In advance.

user3510665
  • 218
  • 3
  • 13
  • Show us your OnPropertyChanged implementation. – Josh L. Apr 22 '15 at 12:37
  • Where is the event being handled? – Josh L. Apr 22 '15 at 12:42
  • 2
    This is not a right way to notify the user about invalid input. If I were the user, I'll never use such an application changes the text which I was entering at the moment. [Refer this](http://social.technet.microsoft.com/wiki/contents/articles/22660.data-validation-in-mvvm.aspx) for the right approach. [Also this](http://blog.magnusmontin.net/2013/08/26/data-validation-in-wpf/) – Sriram Sakthivel Apr 22 '15 at 12:46
  • @JoshL. im not handled that, What i suppose to do now. – user3510665 Apr 22 '15 at 12:46
  • yes Mr @SriramSakthivel but for i have just two three variables so. and Thank you for alternative. – user3510665 Apr 22 '15 at 13:01

3 Answers3

2

I would change your xaml code this way :

<TextBox Text="{Binding MyVal, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></TextBox>

Now every time your property will change, the view will be notified.

and if the UI is still not updated try adding IsAsync=true :

<TextBox Text="{Binding MyVal, Mode=TwoWay, IsAsync=true}"></TextBox>
Guerudo
  • 361
  • 1
  • 7
0

Your example easily works when I use it in WPF app. Rembember that the trigger fires when focus is lost on the control. I've added second textbox, so when you change focus on it, the first TextBox with binding will fire the event.

View

namespace WpfApplication1
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.DataContext = new ViewModel();
            InitializeComponent();
        }
    }
}

View (XAML)

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="223,173,0,0" TextWrapping="Wrap" Text="{Binding MyVal, Mode=TwoWay}" VerticalAlignment="Top" Width="120"/>
        <TextBox HorizontalAlignment="Left" Height="23" Margin="281,252,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>

    </Grid>
</Window>

ViewModel

namespace WpfApplication1
{
    class ViewModel : INotifyPropertyChanged
    {
        private string myVar;

        public string MyVal
        {
            get
            {
                return myVar;
            }
            set
            {
                if (value.Length > 6)
                    myVar = value;
                else
                    myVar = "Not a valid INPUT";
               NotifyPropertyChanged("MyVal");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }


        public ViewModel() { }
    }
}
mwilczynski
  • 3,062
  • 1
  • 17
  • 27
0

The problem is that you are changing the value in the setter, and then firing the INPC event directly. However, since the value is being currently changed anyway, the TextBox ignores the event. See also this question.

This exact implementation of this was changed several times in .NET 3.5/4.0/4.5, so it currently (4.5) works as you expect (but has other side effects, ex. when binding to a double).

The easiest solution for you would be firing the INPC event with a slight delay, which means the TextBox is forced to read the (possibly updated) value again:

Dispatcher.CurrentDispatcher.BeginInvoke(NotifyPropertyChanged("MyVal"));
Community
  • 1
  • 1
Daniel Rose
  • 17,233
  • 9
  • 65
  • 88