12-27-2018 09:29 AM
Hello,
I am interested in customizing the NI NumericTextBoxDouble WPF control. My goal is to end up with a NumericTextBoxDouble user control that looks like the screenshot below. For the custom control I would like to inherit from the NumericTextBoxDouble class (since it has all the functionality I need and is what my code currently uses) and then customize/override the controls appearance. I'm not exactly sure where to get started and I have few questions (I'm not even sure if these are the right questions to ask)...
Any advice is appreciated, thanks!
12-27-2018 01:43 PM - edited 12-27-2018 01:46 PM
The NumericTextBox
is designed as a first-class WPF control, so it supports replacing the control template to customize the appearance of the existing control. You can create a derived control to add additional functionality, but it is not required for purely visual changes.
You can modify the control template in Visual Studio by right-clicking the control and selecting “Edit Template”. This will give you a local copy of the template to work from. Using that as a starting point, I was able to create this simplified control style (i.e. without any interaction triggers, or advanced configuration support):
<Style x:Key="CustomNumericTextBoxDoubleStyle" TargetType="{x:Type ni:NumericTextBoxDouble}"> <Setter Property="Padding" Value="5"/> <Setter Property="TextAlignment" Value="Center"/> <Setter Property="Background" Value="#FF673AB7"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="FontSize" Value="20"/>
<Setter Property="FontWeight" Value="SemiBold"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ni:NumericTextBoxDouble}"> <ControlTemplate.Resources> <ScaleTransform x:Key="Flip" ScaleY="-1" /> <Style x:Key="SpinnerButtonStyle" TargetType="{x:Type RepeatButton}"> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Padding" Value="0,-3,0,0"/> <Setter Property="Background" Value="#FFB39DDB"/> <Setter Property="Content" Value="⬆"/> <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Border Background="{TemplateBinding Background}" CornerRadius="3,3,0,0" > <ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ControlTemplate.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="0.75*"/> <RowDefinition Height="1.00*"/> <RowDefinition Height="0.75*"/> </Grid.RowDefinitions> <RepeatButton Grid.Row="0" Style="{StaticResource SpinnerButtonStyle}" Command="{x:Static niPrimitives:ControlCommands.IncrementCommand}" /> <TextBox x:Name="PART_ValueInput" Grid.Row="1" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Cursor="IBeam" CaretBrush="{TemplateBinding Foreground}" Foreground="{TemplateBinding Foreground}" TextAlignment="{TemplateBinding TextAlignment}" Text="{Binding FormattedValue, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" /> <RepeatButton Grid.Row="2" Style="{StaticResource SpinnerButtonStyle}" Command="{x:Static niPrimitives:ControlCommands.DecrementCommand}" RenderTransform="{StaticResource Flip}" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
Using the custom style, and the engineering value formatter from this answer as a named resource in the code (this.Resources["SecondsFormatter"] = new EngineeringValueFormatter( "S0's'" );
), the final example looks like this:
<ni:NumericTextBoxDouble Style="{DynamicResource CustomNumericTextBoxDoubleStyle}" Value="0.5" ValueFormatter="{StaticResource SecondsFormatter}" />