Reputation: 1155
I am using attached properties to limit the input into a textbox. Now I would like to display the min and max limit in a tooltip but the tooltip either displays '0' for the two values or 'DependencyProperty.UnsetValue'. What's wrong with my bindings?
<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>
(The Converter just appends the two values like (min:max)). For the Binding with {RelativeSource Self} I always get '0'. Searching for the parent element results in the 'UnsetValue'.
I also would like to put the tooltip part into a text box style and use a trigger to check if the inputmode is numeric.
Parts of the 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;
}
}
}
The min and max values are used in the AllowNumberOnly which composes the value from the input digits and checks if it exceeds one of the limits.
EDIT:
I simplified the code and removed the converter to be sure it's not the converter or the multibinding.
<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>
In the InputService I added default values to the min and max properties like this:
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
});
But still the tooltip shows '(0)'.
EDIT:
Ok, this one works:
<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>
I removed the TextBlock around the MultiBinding and the binding to relativesource self seems to work. What does not work anymore is the StringFormat. If defined in the MultiBinding, it will be ignored. If I define it as ContentStringFormat in a surrounding ToolTip, the bindings do not work anymore. Any suggestions?
Upvotes: 0
Views: 2374
Reputation: 69959
Your Binding
syntax in your first line looks perfect, so I'm guessing that you have another problem. I have successfully used the following Path
syntax:
<Binding Path="(Namespace:ClassName.PropertyName)" RelativeSource="{RelativeSource
AncestorType=ControlClassName}"/>
But that is equivalent to your example:
<Binding Path="(Namespace:ClassName.PropertyName)" RelativeSource="{RelativeSource
Mode=FindAncestor, AncestorType={x:Type ControlClassName}}"/>
I can also confirm that the declaration of your Attached Properties
are perfectly fine... no problems there either. However, I'm wondering what would happen if you set default values for your Min
and Max
properties... maybe you're getting an DependencyProperty.UnsetValue
because that property... has no value?
Upvotes: 1