1

WPF has Decorator class which can contain a single child element.

Windows Runtime has no Decorator class but has similar Border class which also can contain child element. Unfortunately Border class is sealed.

I can derive from Control and write a ControlTemplate with ContentPresenter for my child.

How the Border class is written? Here's my example which is not working.

[ContentProperty(Name = "Child")]
public class TextBlockDecorator : FrameworkElement
{
    public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(
        "Child", typeof(TextBlock), typeof(TextBlockDecorator), new PropertyMetadata(null));

    public TextBlock Child
    {
        get { return (TextBlock)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }
}

When I use it Child TextBlock is not shown. How can I add it as a Child to my Decorator element? I think, I'm missing some call like AddVisualChild... or similar

norekhov
  • 3,915
  • 25
  • 45

1 Answers1

1

Windows::UI::Xaml doesn't have the Decorator concept that WPF does. The adornment layer is unique to WPF and not implemented in other Xaml frameworks such as Silverlight and Windows::UI::Xaml. You can create a control which contains a child control (or controls) and draws around them, but you can't do it exactly the same way Windows::UI::Xaml::Controls::Border does. Border is a FrameworkElement rather than a Control and there isn't external access to the needed rendering.

For your use I'd create a custom control derived from ContentControl and then edit the template to show the desired decorations. By using a ContentControl and ContentPresenter you can use the same "Decorator" for any content and not hard-code it to TextBlocks.

Here's a quick demo that puts a circle at the four corners:

Xaml:

<Style TargetType="local:Decorator" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Decorator">
                <Grid
                    Background="{TemplateBinding Background}"
                    MinHeight="30"
                    >
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"/>
                    <Ellipse Height="10" Width="10" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                    <Ellipse Height="10" Width="10" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
                    <Ellipse Height="10" Width="10" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" HorizontalAlignment="Right" VerticalAlignment="Top"/>
                    <Ellipse Height="10" Width="10" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Code (unchanged from the Templated Control template):

public sealed class Decorator : ContentControl
{
    public Decorator()
    {
        this.DefaultStyleKey = typeof(Decorator);
    }
}
Rob Caplan - MSFT
  • 21,714
  • 3
  • 32
  • 54
  • Thanks! What I don't understand about it - why everything is "sealed" and "internal". Even to modify behaviors i need to use some reflector tool. – norekhov Nov 20 '14 at 04:43