Neil B
Neil B

Reputation: 2224

WPF CustomControl style not inherited by Child Control

I'm trying to learn how to make a custom control. I've been searching all afternoon, but can't get my properties to be used by the child controls.

For example my TextBox subclass is TextBoxCalculator. In the control template I have a textbox and a popup.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:Controls">

    <Style TargetType="local:TextBoxCalculator" BasedOn="{StaticResource {x:Type TextBox}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:TextBoxCalculator">

                    <Grid Name="ucGrid">
                        <TextBox Name="AmountTb" Text="{Binding Text }">
                            <!--<TextBox.Style>
                                <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
                                ... How can I make this textbox style follow the one specified in the window XAML?
                                </Style>
                            </TextBox.Style>-->
                        </TextBox>
                        <Popup Name="calPopup"  Placement="Top" StaysOpen="False">
                          ... some content
                        </Popup>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

In my window I use the control like this:

    <Style TargetType="{x:Type controls1:TextBoxCalculator}" x:Key="RightCellEditCalc">
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="TextAlignment" Value="Right"/>
        <Setter Property="Background" Value="Red"/>
        <Setter Property="BorderThickness" Value="0"/>
    </Style>

<controls1:TextBoxCalculator Text="{Binding Amount, UpdateSourceTrigger=LostFocus}" 
                        DecimalPlaces="2"
                        AutoPlaceDecimalPoint="True"
                        Style="{StaticResource RightCellEditCalc}"
                        Background="Green">
</controls1:TextBoxCalculator>

I would expect the background to be green, but it is white instead. An the other hand the TextAlignment = Right seems to be working. What am I missing?

Upvotes: 0

Views: 721

Answers (2)

mm8
mm8

Reputation: 169400

It makes no sense to define a TextBox element in the ControlTemplate of another custom TextBox control.

If you want to create a custom template for your control and base it on the default template of the TextBox control, you could right-click on a TextBox element in design mode in Visual Studio or in Blend and choose Edit Template->Edit a Copy to copy the default template into your XAML markup and then edit it as per your requirements.

This is how it looks like on Windows 8 and later:

<ControlTemplate TargetType="{x:Type TextBox}">
    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Opacity" TargetName="border" Value="0.56"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocused" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

It uses TemplateBindings to bind properties of the Border element in the template to the corresponding property of the TextBox control itself.

Upvotes: 1

CodeLife
CodeLife

Reputation: 1

You are not binding the background.binding it at the place you want inside your ControlTemplate.For example

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:Controls">

<Style TargetType="local:TextBoxCalculator" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:TextBoxCalculator">

                <Grid Name="ucGrid">
                    <TextBox Name="AmountTb" Text="{Binding Text }" Background="{TemplateBinding Background}">
                        <!--<TextBox.Style>
                            <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
                            ... How can I make this textbox style follow the one specified in the window XAML?
                            </Style>
                        </TextBox.Style>-->
                    </TextBox>
                    <Popup Name="calPopup"  Placement="Top" StaysOpen="False">
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

you can use the background now.

Upvotes: 0

Related Questions