0

我正在使用附加属性来限制对文本框的输入。现在我想在工具提示中显示最小和最大限制,但工具提示显示两个值的“0”或“DependencyProperty.UnsetValue”。我的绑定有什么问题?

<TextBox Text="{Binding Value}"
            Helper:InputService.InputMode="Numeric"
            Helper:InputService.Min="7"
            Helper:InputService.Max="{Binding Limit}">
            <TextBox.ToolTip>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding Converter="{converters:StringsToStringMultiConverter}" ConverterParameter=":" StringFormat="{}({0})">
                        <Binding Path="(Helper:InputService.Min)" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TextBox}}"/>  
                        <Binding Path="(Helper:InputService.Max)" RelativeSource="{RelativeSource Self}"/> 
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </TextBox.ToolTip>
        </TextBox>

(转换器只是附加两个值,如 (min:max))。对于与 {RelativeSource Self} 的绑定,我总是得到“0”。搜索父元素会得到“UnsetValue”。

我还想将工具提示部分放入文本框样式中,并使用触发器检查输入模式是否为数字。

输入服务的部分:

/// <summary>
/// The attached property for the input mode.
/// </summary>
public static readonly DependencyProperty InputModeProperty = DependencyProperty.RegisterAttached(
  "InputMode",
  typeof (InputMode),
  typeof (InputService),
  new UIPropertyMetadata(InputMode.All, OnInputModeChanged));

/// <summary>
/// The attached property for checking the min limit of a number. Only applied if input mode is Numeric.
/// </summary>
public static readonly DependencyProperty MinProperty = DependencyProperty.RegisterAttached(
  "Min",
  typeof (int),
  typeof (InputService));

/// <summary>
/// The attached property for checking the max limit of a number. Only applied if input mode is Numeric.
/// </summary>
public static readonly DependencyProperty MaxProperty = DependencyProperty.RegisterAttached(
  "Max",
  typeof (int),
  typeof (InputService));


private static void OnInputModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  var mode = (InputMode) e.NewValue;

  if (d is TextBox)
  {
    var textBox = (TextBox) d;
    var textPastedEventHandler = new RoutedEventHandler(OnTextPasted);
    textBox.AddHandler(CommandManager.PreviewExecutedEvent, textPastedEventHandler, true);

    if (mode == InputMode.Numeric)
    {
      textBox.PreviewTextInput += AllowNumbersOnly;
    }
    else
    {
      textBox.PreviewTextInput -= AllowNumbersOnly;
    }        
  }
}

最小值和最大值在 AllowNumberOnly 中使用,它由输入数字组成值并检查它是否超过限制之一。

编辑:

我简化了代码并删除了转换器,以确保它不是转换器或多重绑定。

<TextBox Text="{Binding Value}"
            Helper:InputService.InputMode="Numeric"
            Helper:InputService.Min="7"
            Helper:InputService.Max="{Binding Limit}">
            <TextBox.ToolTip>
                <TextBlock>
                    <TextBlock.Text>
                        <Binding Path="(Helper:InputService.Min)" RelativeSource="{RelativeSource Self}" StringFormat="{}({0})"/>                             
                    </TextBlock.Text>
                </TextBlock>
            </TextBox.ToolTip>
        </TextBox>

在 InputService 中,我向 min 和 max 属性添加了默认值,如下所示:

   public static readonly DependencyProperty MinProperty = DependencyProperty.RegisterAttached(
  "Min",
  typeof(int),
  typeof(InputService),
  new PropertyMetadata()
     {
       DefaultValue = 0
     });

   public static readonly DependencyProperty MaxProperty = DependencyProperty.RegisterAttached(
  "Max",
  typeof(int),
  typeof(InputService),
  new PropertyMetadata()
    {
      DefaultValue = int.MaxValue
    });

但工具提示仍然显示“(0)”。

编辑:

好的,这个有效:

<TextBox Text="{Binding Value}"
            Helper:InputService.InputMode="Numeric"
            Helper:InputService.Min="7"
            Helper:InputService.Max="{Binding Limit}">
       <TextBox.ToolTip>
          <MultiBinding Converter="{converters:StringsToStringMultiConverter}" ConverterParameter=":">
             <Binding Path="(Helper:InputService.Min)" RelativeSource="{x:Static RelativeSource.Self}"/>
             <Binding Path="(Helper:InputService.Max)" RelativeSource="{x:Static RelativeSource.Self}"/>
           </MultiBinding>
       </TextBox.ToolTip>
  </TextBox>

我删除了 MultiBinding 周围的 TextBlock,并且绑定到 relativesource self 似乎有效。不再起作用的是 StringFormat。如果在 MultiBinding 中定义,它将被忽略。如果我在周围的 ToolTip 中将其定义为 ContentStringFormat,则绑定不再起作用。有什么建议么?

4

1 回答 1

1

Binding在第一行中的语法看起来很完美,所以我猜您还有另一个问题。我已成功使用以下Path语法:

<Binding Path="(Namespace:ClassName.PropertyName)" RelativeSource="{RelativeSource 
    AncestorType=ControlClassName}"/>  

但这等同于您的示例:

<Binding Path="(Namespace:ClassName.PropertyName)" RelativeSource="{RelativeSource 
    Mode=FindAncestor, AncestorType={x:Type ControlClassName}}"/> 

我还可以确认您的声明Attached Properties完全没问题……也没有问题。但是,我想知道如果你为你的MinMax属性设置默认值会发生什么......也许你得到一个DependencyProperty.UnsetValue因为那个属性......没有价值?

于 2013-09-12T08:50:58.810 回答