0

I have a custom control and I would like to tell every TextBlock inside to use TextBlock.TextTrimming = CharacterEllipsis but I dont want to set that property on each individually. I mean even if later the user defines a ContentTemplate and places it inside my custom control and that ContentTemplate includes some Textblocks, they should automatically have set TextBlock.TextTrimming = CharacterEllipsis.

How do i do that? Any help please?

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
cyberist
  • 107
  • 1
  • 10
  • Create a style and have it apply to TextBlocks ??? – Ravi Y Dec 18 '12 at 11:40
  • `` Do you mean this? Wouldnt this affect ever textbox the complete Window.xaml if the user later implies my custom control assembly namespace? – cyberist Dec 18 '12 at 11:45
  • Yes it would, an alternative is to create and set the style in your code. You could define that in the constructor of your custom control, and that would force any inherited controls to use it. Check this: http://stackoverflow.com/questions/1729368/creating-a-style-in-code-behind – Ravi Y Dec 18 '12 at 11:51
  • 1
    A default TextBlock style in `UserControl.Resources` would not affect TextBlocks outside the UserControl. – Clemens Dec 18 '12 at 11:55
  • @ryadavilli i did that so but it seems its not working. The textblocks inside doesnt update the value. – cyberist Dec 18 '12 at 11:55
  • @Clemens Its a custom control not UserControl – cyberist Dec 18 '12 at 11:56
  • An alternative would be an inheriting attached property. When applied to an element tree, it would set the proper TextTrimming when its target object is a TextBlock. – Clemens Dec 18 '12 at 12:17
  • @Clemens how do i create such an inheriting property that callsback a method as soon its been added to a control? – cyberist Dec 18 '12 at 12:32

1 Answers1

3

You could create an attached property with property value inheritance and apply that to your custom control, for example in its constructor. The attached property would copy its value to the target object, whenever the target object is a TextBlock.

public class CustomControl : ContentControl
{
    public CustomControl()
    {
        SetTextTrimming(this, TextTrimming.CharacterEllipsis);
    }

    public static readonly DependencyProperty TextTrimmingProperty =
        DependencyProperty.RegisterAttached(
            "TextTrimming", typeof(TextTrimming), typeof(CustomControl),
            new FrameworkPropertyMetadata(
                default(TextTrimming),
                FrameworkPropertyMetadataOptions.Inherits,
                TextTrimmingPropertyChanged));

    public static TextTrimming GetTextTrimming(DependencyObject obj)
    {
        return (TextTrimming)obj.GetValue(TextTrimmingProperty);
    }

    public static void SetTextTrimming(DependencyObject obj, TextTrimming value)
    {
        obj.SetValue(TextTrimmingProperty, value);
    }

    private static void TextTrimmingPropertyChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var textBlock = obj as TextBlock;

        if (textBlock != null)
        {
            textBlock.TextTrimming = (TextTrimming)e.NewValue;
        }
    }
}

Note that there is no need to define this TextTrimming attached property in a derived control class. You could also define it in a special helper class, which does not even need to be derived from DependencyObject.

The property also work fine with any other control that uses TextBoxes in their visual tree, for example a standard ContentControl:

<ContentControl local:CustomControl.TextTrimming="WordEllipsis"
                Content="Some sample text to be trimmed"/>
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • great idea but its not working for TextBoxes inside a ContentControl – cyberist Dec 18 '12 at 13:05
  • I works fine for me with exactly the code above, a class CustomControl derived from ContentControl. Please check again if you copied everything properly. – Clemens Dec 18 '12 at 13:27
  • I found it out! In order for this to work, you would need the column in grid of your ContentTemplate to have a * size, otherwise it will tell the TextBlock that it has as much space as it wants, even if it doesn't. Auto sized columns won't restrict the content to the bounds of a grid. – cyberist Dec 18 '12 at 13:31