UpdateSourceTrigger = PropertyChanged and Converter

I have a simple Converterone that adds a "+" to a positive number that is entered at TextBox. When a number is entered, I want to initiate some actions, but I do not want to wait until the tag TextBoxloses focus: I want to immediately update the binding when the user enters text.

The TextBoxdefault behavior is that when the user moves away from the field, the binding source is updated (UpdateSourceTrigger = LostFocus). In this case, my converter works as expected, and + is added. However, when I change it to the following, + is never added.

<TextBox Text="{Binding Value, Converter={StaticResource PlusConverter}, UpdateSourceTrigger=PropertyChanged}" />

I can imagine that there is a good reason why my .Convert () converter method is not being called. I would like to have the following behavior:

  • When users enter text, the source is updated immediately.
  • When it TextBoxloses focus, + is added.

Now I am looking for a good, but especially GENERIC way to do this (since I have a lot of these TextBoxes in my application). So far, I have not been able to find a suitable solution.

+3
source share
4 answers

Thank you for your responses! I considered this question myself a little further and came up with the following solution (of which I am not quite satisfied, but it works fine)

I created a CustomControl that adds functionality to a TextBox.

LostFocus , .

, , ( , TextBox). Setter . .

, "PlusTextBox", , .

public class TextBoxEx : TextBox
{
    public TextBoxEx()
    {
        AddHandler(LostFocusEvent,
          new RoutedEventHandler(CallConverter), true);
    }

    public Type SourceType
    {
        get { return (Type)GetValue(SourceTypeProperty); }
        set { SetValue(SourceTypeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SourceType.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SourceTypeProperty =
        DependencyProperty.Register("SourceType", typeof(Type), typeof(TextBoxEx), new UIPropertyMetadata(null));

    private static void CallConverter(object sender, RoutedEventArgs e)
    {
        TextBoxEx textBoxEx = sender as TextBoxEx;
        if (textBoxEx.Style == null) {
            return;
        }
        if (textBoxEx.SourceType == null) {
        }
        foreach (Setter setter in textBoxEx.Style.Setters) {
            if (setter.Property.ToString() == "Text") {
                if (! (setter.Value is Binding) ) {
                    return;
                }
                Binding binding = setter.Value as Binding;
                if (binding.Converter == null) {
                    return;
                }
                object value = binding.Converter.ConvertBack(textBoxEx.Text, textBoxEx.SourceType, binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture);
                value = binding.Converter.Convert(value, typeof(string), binding.ConverterParameter, System.Globalization.CultureInfo.CurrentCulture);
                if (!(value is string)) {
                    return;
                }
                textBoxEx.Text = (string)value;
            }
        }
    }
}
+1

Kent B, .

1 ( TextBlock, , ).

, 2, TextBox "+" , . , , IConverter. , .

, , - , . ( DataBinding, ). / - "LostFocus" TextBoxes, , .

TextBox UserControl. WPFToolkit DatePicker, : , DateTime ( ) DateTime .

.

+1

, , , , - TextBox PART_ContentHost , TextBlock +/- ; .. TextBox :

Control
- Border
-- PART_ContentHost (the actual editing part)

Control
- Border
-- Horizontal StackPanel
--- TextBlock (contains +/- sign, has 2px right margin)
--- PART_ContentHost (actual editable section)

Then bind the contents of the TextBlock to the text, but with a converter that either writes "+" or "-". Thus, the user cannot delete the +/- part, and you do not need to worry about its parsing; it also makes your job easier if you want to do something like a negative red sign or something else.

+1
source

In your converter, could you just check the current keyboard focus? Sort of:

TextBox focusedTextBox = Keyboard.FocusedElement as TextBox;
if (focusedTextBox == null || focusedTextBox != senderOrWhatever)
{
 ' this is where you'd add the +, because the textbox doesn't have focus.
}
0
source

Source: https://habr.com/ru/post/1710344/


All Articles