NZJames
NZJames

Reputation: 5055

Binding a control property to a style

I have a busy decorator that is as follows

<controls:BusyDecorator x:Name="Busy" BusyStyle="{StaticResource busyStyle}" FadeTime="00:00:00.2" IsBusyIndicatorShowing="{Binding IsBusy}" Tag="Description">

And the style

<Style x:Key="busyStyle" TargetType="{x:Type Control}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Control}">
                <ControlTemplate.Resources>
                    <Style TargetType="{x:Type Rectangle}">
                        <Setter Property="Width" Value="8" />
                        <Setter Property="Height" Value="16" />
                        <Setter Property="Stroke" Value="Black" />
                        <Setter Property="StrokeThickness" Value="1" />
                        <Setter Property="RadiusX" Value="2" />
                        <Setter Property="RadiusY" Value="2" />
                        <Setter Property="RenderTransformOrigin" Value=".5,.5" />
                    </Style>
                </ControlTemplate.Resources>
                <Canvas Width="64" Height="64">
                    <Rectangle Canvas.Left="24">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="top" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="10" Canvas.Top="6">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="-45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="topLeft" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Top="24" Width="16" Height="8">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="left" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="10" Canvas.Top="34">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottomLeft" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="24" Canvas.Top="40">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottom" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="38" Canvas.Top="34">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="-45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottomRight" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Top="24" Canvas.Left="38" Width="16" Height="8">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="right" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="38" Canvas.Top="6">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="topRight" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <TextBlock Canvas.Left="1" Canvas.Top="64" FontSize="11" Foreground="White" Text="{TemplateBinding Tag}" />
                </Canvas>

What I want is to be able to set the text on the spinner to whatever I like at run time. For now I am hard coding it on the Tag property as a POC but I don't get any text displayed in the spinner. If I change the

{TemplateBinding Tag}

at the bottom of the style to a plain hard coded text value, it displays the text.

How can I propogate a text string through from the parent control to display on the style rendering?

Updated

I have a class representing this control, as follows

 [StyleTypedProperty(Property = "BusyStyle", StyleTargetType = typeof (Control))]
    public class BusyDecorator : Decorator
{
#region IsBusyIndicatorShowing Property

        /// <summary>
        /// Identifies the IsBusyIndicatorShowing dependency property.
        /// </summary>
        public static readonly DependencyProperty IsBusyIndicatorShowingProperty = DependencyProperty.Register(
            "IsBusyIndicatorShowing",
            typeof (bool),
            typeof (BusyDecorator),
            new FrameworkPropertyMetadata(false,
                                          FrameworkPropertyMetadataOptions.AffectsMeasure,
                                          OnIsShowingChanged));

        /// <summary>
        /// Gets or sets if the BusyIndicator is being shown.
        /// </summary>
        public bool IsBusyIndicatorShowing
        {
            get { return (bool) GetValue(IsBusyIndicatorShowingProperty); }
            set { SetValue(IsBusyIndicatorShowingProperty, value); }
        }

As the style targets the type of Control, I cant template bind to a dependency property I create on the BusyDecorator type. If I change the TargetType of the style to "BusyDecorator" it says it cannot find the Template property?

Upvotes: 0

Views: 1089

Answers (2)

mm8
mm8

Reputation: 169150

BusyDecorator should be a Control:

public class BusyDecorator : Control
...

...with a Template:

<Style x:Key="busyStyle" TargetType="{x:Type local:BusyDecorator}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Control}">
                <ControlTemplate.Resources>
                    <Style TargetType="{x:Type Rectangle}">
                        <Setter Property="Width" Value="8" />
                        <Setter Property="Height" Value="16" />
                        <Setter Property="Stroke" Value="Black" />
                        <Setter Property="StrokeThickness" Value="1" />
                        <Setter Property="RadiusX" Value="2" />
                        <Setter Property="RadiusY" Value="2" />
                        <Setter Property="RenderTransformOrigin" Value=".5,.5" />
                    </Style>
                </ControlTemplate.Resources>
                <Canvas Width="64" Height="64">
                    <Rectangle Canvas.Left="24">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="top" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="10" Canvas.Top="6">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="-45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="topLeft" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Top="24" Width="16" Height="8">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="left" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="10" Canvas.Top="34">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottomLeft" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="24" Canvas.Top="40">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottom" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="38" Canvas.Top="34">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="-45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="bottomRight" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Top="24" Canvas.Left="38" Width="16" Height="8">
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="right" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <Rectangle Canvas.Left="38" Canvas.Top="6">
                        <Rectangle.RenderTransform>
                            <RotateTransform Angle="45" />
                        </Rectangle.RenderTransform>
                        <Rectangle.Fill>
                            <SolidColorBrush x:Name="topRight" Color="#DFDFDF" />
                        </Rectangle.Fill>
                    </Rectangle>
                    <TextBlock Canvas.Left="1" Canvas.Top="64" FontSize="11" Foreground="Blue" Text="{TemplateBinding Tag}" />
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Then this works:

<local:BusyDecorator x:Name="Busy" Style="{StaticResource busyStyle}" Tag="Description" />

A Decorator doesn't have any template and you can't apply a Style with a TargetType of Control to a Decorator either.

Upvotes: 0

zeeshan
zeeshan

Reputation: 56

I believe, by specifying {TemplateBinding Tag} the Textblock is referring to its own Tag, you should probably consider creating a custom control with your BusyContent as a DependencyProperty in that control. Then you can specify {TemplateBinding BusyContent}.

Upvotes: 1

Related Questions