访问绑定中的Attached属性的值

时间:2013-09-12 08:34:28

标签: wpf binding attached-properties

我使用附加属性将输入限制为文本框。 现在我想在工具提示中显示最小和最大限制,但工具提示要么为两个值显示'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'。

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

InputService的部分内容:

/// <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中定义,它将被忽略。如果我在周围的工具提示中将其定义为ContentStringFormat,则绑定不再起作用。 有什么建议吗?

1 个答案:

答案 0 :(得分: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,因为该属性...没有值?