Styling NumericUpDown

Jun 29, 2012 at 10:47 PM

I need to restyle the NumericUpDown so that the the glyphs are customized and are on either side of the WatermarkTextBox. 

I have found the glyphs in the Template and can change them, but how do I go about relaying out the Button spinner to *contain* the TextBox.

Ning Zang has a post on how to restyle the Silverlight NumericControl, is it applicable here? (http://blog.ningzhang.org/2008/11/numericupdown-control-in-silverlight.html) Changing the TextBox to be inside of the ButtonSpinner seems to have no effect.

 

Thanks.

Coordinator
Jul 3, 2012 at 2:49 PM

Hi,

 

If you look at the default template of a NumericUpDown control, you'll notice that the TextBox (WatermarkTextBox) is already inside the ButtonSpinner control.

<ControlTemplate>
   <xctk:ButtonSpinner x:Name="Spinner"
                       ...>
      <xctk:WatermarkTextBox x:Name="TextBox"
                             ... />
   </xctk:ButtonSpinner>
</ControlTemplate>

 

If you want to change the layout of the RepeatButtons, you'll have to re-template the ButtonSpinner that is inside the NumericUpDown control.  Here is a simplified version of the ButtonSpinner's default template.

<ControlTemplate TargetType="{x:Type xctk:ButtonSpinner}">
   <Grid>
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="*" />
         <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>

      <ContentPresenter ... />

      <Grid Grid.Column="1"
            ...>
         <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
         </Grid.RowDefinitions>

         <RepeatButton x:Name="PART_IncreaseButton"
                       ... />

         <RepeatButton x:Name="PART_DecreaseButton"
                       Grid.Row="1"
                       ... />

      </Grid>
   </Grid>
</ControlTemplate>

 

The ContentPresenter will display the content of the ButtonSpinner.  For a NumericUpDown control, this is the TextBox (WatermarkTextBox).

Jul 6, 2012 at 3:32 PM
Edited Jul 6, 2012 at 3:43 PM

That worked perfectly thanks!

I am now trying to put some space between the buttons and the Watermark TextBox. Here is what the layout bit of the template looks like now

 

<ControlTemplate TargetType="{x:Type xctk:ButtonSpinner}">
                    <Grid SnapsToDevicePixels="True">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>

                        <Border x:Name="Border" Grid.ColumnSpan="3"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}" />

                        <ContentPresenter Grid.Column="1"
                                          Margin="{TemplateBinding Padding}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                          Focusable="False"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

                        <RepeatButton x:Name="PART_IncreaseButton"
                                     ...>

                        <RepeatButton x:Name="PART_DecreaseButton" Grid.Column="2"
                                      ... />         
                    </Grid>           
                </ControlTemplate>

 

The " Margin="{TemplateBinding Padding}" " bit is from the original template and it would seem it would add Margin to the TextBox if you set the Padding on the main control. But regardless of what I set the Padding to, it has no effect. 

 

Any ideas?

Coordinator
Jul 6, 2012 at 8:00 PM

Hi,

 

Your ControlTemplate is for the ButtonSpinner.  The Margin that is going to be applied on the ContentPresenter is based on the Padding of the ButtonSpinner.  If you look at the NumericUpDown default ControlTemplate, you'll notice that the ButtonSpinner do not have any Padding.  It would have worked if it was Padding="{TemplateBinding Padding}".

Dec 18, 2014 at 4:58 PM
Setting Opacity = "0" in x:Name="Border" is what worked under my "<Window.Resources":
        <Style TargetType="{x:Type xctk:WatermarkTextBox}">
            <Setter Property="Template" Value="{DynamicResource WatermarkTextBox1}"/>
        </Style>

        <ControlTemplate x:Key="WatermarkTextBox1" TargetType="{x:Type xctk:WatermarkTextBox}">
            <Grid>
                <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="0"/>
                <Border x:Name="MouseOverVisual" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="0">
                    <Border.BorderBrush>
                        <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                            <GradientStop Color="#FF5794BF" Offset="0.05"/>
                            <GradientStop Color="#FFB7D5EA" Offset="0.07"/>
                            <GradientStop Color="#FFC7E2F1" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.BorderBrush>
                </Border>
                <Border x:Name="FocusVisual" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="0">
                    <Border.BorderBrush>
                        <LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
                            <GradientStop Color="#FF3D7BAD" Offset="0.05"/>
                            <GradientStop Color="#FFA4C9E3" Offset="0.07"/>
                            <GradientStop Color="#FFB7D9ED" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.BorderBrush>
                </Border>
                <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                <ContentPresenter x:Name="PART_WatermarkHost" ContentTemplate="{TemplateBinding WatermarkTemplate}" Content="{TemplateBinding Watermark}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Grid>
            <ControlTemplate.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsFocused" Value="False"/>
                        <Condition Property="Text" Value=""/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Visibility" TargetName="PART_WatermarkHost" Value="Visible"/>
                </MultiTrigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Opacity" TargetName="MouseOverVisual" Value="1"/>
                </Trigger>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Opacity" TargetName="FocusVisual" Value="1"/>
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="BorderBrush" TargetName="Border" Value="#FFADB2B5"/>
                    <Setter Property="Background" TargetName="Border" Value="#FFF4F4F4"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    <!--<Setter Property="Opacity" TargetName="Border" Value="0.5"/>-->
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>