3

我有一个简单的Converter方法,可以将“+”符号添加到输入的正数中TextBox。输入数字后,我想启动一些操作,但我不想等到TextBox失去焦点:我想在用户输入文本时立即更新绑定。

a 的默认行为TextBox是当用户离开框时,绑定源会更新(UpdateSourceTrigger=LostFocus)。在这种情况下,我的转换器按预期工作,并添加了 +。但是,当我将其更改为以下内容时,永远不会添加 +。

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

我可以想象没有调用我的 converter.Convert() 方法是有充分理由的。我想有以下行为:

  1. 当用户输入文本时,源会立即更新
  2. TextBox失去焦点时,添加+。

现在我正在寻找一种很好的但特别是通用的方式来做到这一点(因为我的应用程序中有很多这样的文本框)。到目前为止,我还没有想出一个合适的解决方案。

4

4 回答 4

1

同意肯特 B,您需要发布您的转换器代码。

我已经能够让第 1 部分使用一个简单的转换器(我正在绑定第二个未转换的 TextBlock 以显示该值确实正在更新)。

但是,如果我理解您的第 2 部分,您正在尝试让TextBox的文本在失去焦点后用“+”更新。这有点棘手,我认为您无法仅使用 IConverter 来做到这一点。如果可以的话,我也很想知道答案。

您本质上要求的是带水印的输入行为,例如允许用户输入一些数据,并使其格式正确(在底层 DataBinding 和 UI 中)。最快/最脏的解决方案是处理 TextBoxes 的 LostFocus,但由于您在整个应用程序中都使用它,这可能不可行。

您还可以考虑将 TextBox 包装在您自己的 UserControl 中。如果您查看 WPFToolkit 的 DatePicker 实现,它具有类似的行为:允许用户输入自由格式的文本,然后将值自动转换为 DateTime(如果有效)并以本地化格式显示 DateTime。

HTH。

于 2009-06-12T17:35:21.070 回答
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)

然后,将 TextBlock 的内容绑定到文本,但使用写入“+”或“-”的转换器。这样用户就不能删除+/-部分,你也不用担心解析它;如果您想做一些事情,例如将负号变为红色或其他事情,这也使您更容易。

于 2009-06-12T21:31:14.373 回答
1

感谢您的回答!我自己进一步研究了这个问题,并提出了以下解决方案(我并不完全满意,但效果很好)

我创建了一个向 TextBox 添加功能的 CustomControl。

它为 LostFocus 事件提供了一个事件处理程序,当此事件发生时,我的转换器被调用。

但是,我解决转换器的方式不是很令人满意(我从与我的 TextBox 关联的样式中获取它)。Style 有一个用于 Text 属性的 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;
            }
        }
    }
}
于 2009-06-15T08:32:17.850 回答
0

在您的转换器中,您不能只检查键盘的当前焦点吗?就像是:

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.
}
于 2009-07-02T06:25:46.633 回答