【问题标题】:Access the value of an Attached property in a binding访问绑定中附加属性的值
【发布时间】:2013-09-16 13:09:36
【问题描述】:

我正在使用附加属性来限制对文本框的输入。 现在我想在工具提示中显示最小和最大限制,但工具提示显示两个值的“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”。

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

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

【问题讨论】:

    标签: wpf binding attached-properties


    【解决方案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 因为该属性...没有价值?

    【讨论】:

    • 我编辑了我的问题并添加了一些 InputService 的代码。
    • 在我的示例代码中,我肯定设置了最小值和最大值。那么依赖属性怎么可能没有任何价值呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 2017-07-02
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多