Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP TextBox not respecting TwoWay binding when typing

Tags:

c#

textbox

uwp

    <!-- View -->
    <TextBox Text="{Binding str, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

    // View Model
    private string _str;
    public string str
    {
        get { return _str; }
        set
        {
            if (!value.Contains("a"))
                _str = value;

            OnPropertyChanged(nameof(str));
        }
    }

When typing in the TextBox I want it to throw out any invalid characters (in this sample case the letter 'a', but it could really be for anything). For example:

  1. User types 'fds' followed by an 'a'
  2. str detects a, so it doesn't set _str to 'fdsa', keeping it at 'fds' but raises the event anyway to indicate to the view to throw out the 'a'.
  3. In WPF, this results in the textbox containing 'fds'. In UWP, this results in the textbox incorrectly containing 'fdsa' still.

It appears that in UWP when a control has focus, it will not respect the TwoWay binding.

I can create a button that has a Click event that when pressed will update my TextBox correctly.

    private void btn_Click(object sender, RoutedEventArgs e)
    {
        OnPropertyChanged(nameof(str));
    }

We have many ViewModels that we need to use in both WPF and UWP views, and we have this required behavior all over the place. What is a good solution to this problem?

* EDIT *

Came back to the problem after the weekend and it seems to have fixed itself. I have no idea why. I am closing the question for now.

like image 226
Jacob Schultz Avatar asked Nov 13 '15 23:11

Jacob Schultz


1 Answers

You could use a converter to solve your problem, you could elaborate a better converter, in my example I just use a silly converter to demonstrate my idea.

Converter:

 public class Converter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            var someString = value.ToString();
            return someString.Replace("a", "");
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }
}

XAML

<TextBox Text="{Binding Str, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource converter}}"/>

You could use an attached behavior also.

like image 59
Bruno Joaquim Avatar answered Nov 14 '22 21:11

Bruno Joaquim