I have a couple of Masked Input controls on my form, including one date time and a couple of numeric input. I have buttons tied to the controls through events which increase or decrease the value of the control by 1. The values of these controls are bound to variables in my program. Here's the Xaml:
And here's the code-behind:
I want users to be able to change the value of the controls by editing them and have the value of the control change, so that if they make an edit, then hit the up or down arrow buttons, the value increments from the value they edited, not where the value was before they edited the field.
What do I need to change to make this work?
Tony
<UserControl x:Class="CarSystem.CustomControls.TimeSpanSpinner" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:cs="clr-namespace:CarSystem.CustomControls" mc:Ignorable="d" Focusable="True" Loaded="UserControl_Loaded"> <UserControl.Resources> <cs:TimeSpanToDateTimeConverter x:Key="TimeSpanConverter" /> </UserControl.Resources> <Grid Background="{Binding Path=GridBackground, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Width="{Binding Path=Width, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <telerik:RadMaskedDateTimeInput BorderBrush="{Binding Path=BorderBrush, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FlowDirection="{Binding Path=FlowDirection, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Focusable="True" FontFamily="{Binding Path=FontFamily, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontSize="{Binding Path=FontSize, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontStretch="{Binding Path=FontStretch, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontStyle="{Binding Path=FontStyle, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" FontWeight="{Binding Path=FontWeight, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" GotFocus="ValueBox_GotFocus" Grid.Column="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Right" InputBehavior="Insert" IsClearButtonVisible="False" LostFocus="ValueBox_LostFocus" Margin="5" Mask="{Binding Path=Mask, Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Name="ValueBox" SelectionOnFocus="CaretToEnd" SpinMode="PositionAndValue" TabIndex="{Binding Path=TabIndex, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" TextMode="MaskedText" UpdateValueEvent="PropertyChanged" Value="{Binding Path=Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}, Converter={StaticResource TimeSpanConverter}}" VerticalAlignment="Center" /> <RepeatButton Background="{DynamicResource ButtonBackground}" Click="IncrementButton_Click" Focusable="False" Foreground="{DynamicResource ButtonForeground}" Grid.Column="1" IsTabStop="False" Name="IncrementButton"> <Image> <Image.Style> <Style TargetType="{x:Type Image}"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpDay.png" /> <Style.Triggers> <DataTrigger Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeUpNight.png" /> </DataTrigger> </Style.Triggers> </Style> </Image.Style> </Image> </RepeatButton> <RepeatButton Background="{DynamicResource ButtonBackground}" Click="DecrementButton_Click" Focusable="False" Foreground="{DynamicResource ButtonForeground}" Grid.Column="2" IsTabStop="False" Name="DecrementButton"> <Image> <Image.Style> <Style TargetType="{x:Type Image}"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnDay.png" /> <Style.Triggers> <DataTrigger Binding="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:TimeSpanSpinner}}}" Value="NightTime"> <Setter Property="Source" Value="/CustomControls;component/Resources/VolumeDnNight.png" /> </DataTrigger> </Style.Triggers> </Style> </Image.Style> </Image> </RepeatButton> </Grid> </UserControl> And here's the code-behind:
public partial class TimeSpanSpinner : UserControl { public static readonly DependencyProperty FocusedBackgroundProperty = DependencyProperty.Register( "FocusedBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty FocusedForegroundProperty = DependencyProperty.Register( "FocusedForeground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static DependencyProperty GridBackgroundProperty = DependencyProperty.Register( "GridBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( Brushes.Transparent ) ); public static readonly DependencyProperty MaskProperty = DependencyProperty.Register( "Mask", typeof( string ), typeof( TimeSpanSpinner ), new PropertyMetadata( "HH:mm:ss.fff" ) ); public static readonly DependencyProperty TimeOfDayModeProperty = DependencyProperty.Register( "TimeOfDayMode", typeof( TimesOfDay ), typeof( TimeSpanSpinner ), new FrameworkPropertyMetadata( TimesOfDay.DayTime, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback( OnTimeOfDayInvalidated ) ) ); public static readonly DependencyProperty UnfocusedBackgroundProperty = DependencyProperty.Register( "UnfocusedBackground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty UnfocusedForegroundProperty = DependencyProperty.Register( "UnfocusedForeground", typeof( Brush ), typeof( TimeSpanSpinner ), new PropertyMetadata( null ) ); public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof( TimeSpan ), typeof( TimeSpanSpinner ), new PropertyMetadata( TimeSpan.Zero ) ); public Brush FocusedBackground { get { return (Brush) GetValue( FocusedBackgroundProperty ); } set { SetValue( FocusedBackgroundProperty, value ); } } public Brush FocusedForeground { get { return (Brush) GetValue( FocusedForegroundProperty ); } set { SetValue( FocusedForegroundProperty, value ); } } public Brush GridBackground { get { return (Brush) GetValue( GridBackgroundProperty ); } set { SetValue( GridBackgroundProperty, value ); } } public string Mask { get { return (string) GetValue( MaskProperty ); } set { SetValue( MaskProperty, value ); } } public TimesOfDay TimeOfDayMode { get { return (TimesOfDay) GetValue( TimeOfDayModeProperty ); } set { SetValue( TimeOfDayModeProperty, value ); } } public Brush UnfocusedBackground { get { return (Brush) GetValue( UnfocusedBackgroundProperty ); } set { SetValue( UnfocusedBackgroundProperty, value ); } } public Brush UnfocusedForeground { get { return (Brush) GetValue( UnfocusedForegroundProperty ); } set { SetValue( UnfocusedForegroundProperty, value ); } } public TimeSpan Value { get { return (TimeSpan) GetValue( ValueProperty ); } set { SetValue( ValueProperty, value ); } } public TimeSpanSpinner() { InitializeComponent(); } private void DecrementButton_Click( object sender, RoutedEventArgs e ) { // Decrement the Value in the ValueBox ValueBox.CallSpin( false ); } private void IncrementButton_Click( object sender, RoutedEventArgs e ) { ValueBox.CallSpin( true ); } private void OnTimeOfDayModeChanged( TimesOfDay newTimeofDayMode ) { if ( FocusedBackground != null && UnfocusedBackground != null ) { ValueBox.Background = ValueBox.IsFocused ? FocusedBackground : UnfocusedBackground; } if ( FocusedForeground != null && UnfocusedForeground != null ) { ValueBox.Foreground = ValueBox.IsFocused ? FocusedForeground : UnfocusedForeground; } } private static void OnTimeOfDayInvalidated( DependencyObject d, DependencyPropertyChangedEventArgs e ) { TimeSpanSpinner spinner = (TimeSpanSpinner) d; spinner.OnTimeOfDayModeChanged( (TimesOfDay) e.NewValue ); } private void UserControl_Loaded( object sender, RoutedEventArgs e ) { if ( FocusedBackground == null && UnfocusedBackground == null ) { ValueBox.Background = Background; } if ( FocusedForeground == null && UnfocusedForeground == null ) { ValueBox.Foreground = Foreground; } } private void ValueBox_GotFocus( object sender, RoutedEventArgs e ) { if ( FocusedBackground != null ) { ValueBox.Background = FocusedBackground; } if ( FocusedForeground != null ) { ValueBox.Foreground = FocusedForeground; } } private void ValueBox_LostFocus( object sender, RoutedEventArgs e ) { if ( UnfocusedBackground != null ) { ValueBox.Background = UnfocusedBackground; } if ( UnfocusedForeground != null ) { ValueBox.Foreground = UnfocusedForeground; } } } } I want users to be able to change the value of the controls by editing them and have the value of the control change, so that if they make an edit, then hit the up or down arrow buttons, the value increments from the value they edited, not where the value was before they edited the field.
What do I need to change to make this work?
Tony