Masked Input Control does not change value when user types in control

5 posts, 0 answers
  1. Tony
    Tony avatar
    111 posts
    Member since:
    May 2011

    Posted 05 Jun 2012 Link to this post

    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:

    <UserControl x:Class="CarSystem.CustomControls.TimeSpanSpinner"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 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
  2. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 08 Jun 2012 Link to this post

    Hello Tony,

    I am not sure if I understand the issue correctly. I used your code snippets to create a sample project and the spinning functionality of the RadMaskedDateTimeInput worked as expected. Can you please have a look at the solution and let me know the steps to reproduce the issue? That would help me better understand the case.

    Thank you in advance.

    Greetings,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. UI for WPF is Visual Studio 2017 Ready
  4. Tony
    Tony avatar
    111 posts
    Member since:
    May 2011

    Posted 08 Jun 2012 Link to this post

    My mistake, I grabbed the wrong code.

    Here's the xaml for a user control that uses the RadMaskedNumericInput control:

    <UserControl x:Class="CarSystem.CustomControls.NumberSpinner"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 xmlns:cs="clr-namespace:CarSystem.CustomControls"
                 mc:Ignorable="d"
                 Focusable="True"
                 Loaded="UserControl_Loaded">
      
        <Grid Background="{Binding Path=GridBackground, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}" 
              Width="{Binding Path=Width, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <telerik:RadMaskedNumericInput BorderBrush="{Binding Path=BorderBrush, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           FlowDirection="{Binding Path=FlowDirection, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           Focusable="True"
                                           FontFamily="{Binding Path=FontFamily, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           FontSize="{Binding Path=FontSize, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           FontStretch="{Binding Path=FontStretch, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           FontStyle="{Binding Path=FontStyle, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           FontWeight="{Binding Path=FontWeight, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           GotFocus="ValueBox_GotFocus"
                                           Grid.Column="0"
                                           HorizontalAlignment="Stretch"
                                           HorizontalContentAlignment="Right"
                                           InputBehavior="Insert"
                                           IsClearButtonVisible="False"
                                           LostFocus="ValueBox_LostFocus"
                                           Margin="5"
                                           Mask="{Binding Path=Mask, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           Name="ValueBox"
                                           SelectionOnFocus="CaretToEnd"
                                           SpinMode="PositionAndValue"
                                           TabIndex="{Binding Path=TabIndex, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           TextMode="PlainText"
                                           UpdateValueEvent="PropertyChanged"
                                           Value="{Binding Path=Value, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type cs:NumberSpinner}}}"
                                           VerticalAlignment="Center" />
            <RepeatButton Click="IncrementButton_Click"
                          Focusable="False"
                          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:NumberSpinner}}}"
                                             Value="NightTime">
                                    <Setter Property="Source"
                                            Value="/CustomControls;component/Resources/VolumeUpNight.png" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
            </RepeatButton>
            <RepeatButton Click="DecrementButton_Click"
                          Focusable="False"
                          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:NumberSpinner}}}"
                                             Value="NightTime">
                                    <Setter Property="Source"
                                            Value="/CustomControls;component/Resources/VolumeDnNight.png" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
            </RepeatButton>
        </Grid>
          
    </UserControl>

    And the code behind:

    public partial class NumberSpinner : UserControl {
      
        public static readonly DependencyProperty FocusedBackgroundProperty =
            DependencyProperty.Register( "FocusedBackground", typeof( Brush ), typeof( NumberSpinner ), new PropertyMetadata( null ) );
      
        public static readonly DependencyProperty FocusedForegroundProperty =
            DependencyProperty.Register( "FocusedForeground", typeof( Brush ), typeof( NumberSpinner ), new PropertyMetadata( null ) );
      
        public static DependencyProperty GridBackgroundProperty =
            DependencyProperty.Register( "GridBackground", typeof( Brush ), typeof( NumberSpinner ), new PropertyMetadata( Brushes.Transparent ) );
      
        public static readonly DependencyProperty IncrementProperty =
            DependencyProperty.Register( "Increment", typeof( double ), typeof( NumberSpinner ), new PropertyMetadata( 1.0 ) );
                      
        public static readonly DependencyProperty MaskProperty = 
            DependencyProperty.Register( "Mask", typeof( string ), typeof( NumberSpinner ), new PropertyMetadata( "#9.2" ) );
      
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register( "Maximum", typeof( double ), typeof( NumberSpinner ), 
                                             new PropertyMetadata( double.NaN, new PropertyChangedCallback( OnMaximumInvalidated ) ) );
      
        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.Register( "Minimum", typeof( double ), typeof( NumberSpinner ),
                                             new PropertyMetadata( double.NaN, new PropertyChangedCallback( OnMinimumInvalidated ) ) );
      
        public static readonly DependencyProperty TimeOfDayModeProperty =
            DependencyProperty.Register( "TimeOfDayMode", typeof( TimesOfDay ), typeof( NumberSpinner ),
                                         new FrameworkPropertyMetadata( TimesOfDay.DayTime,
                                             FrameworkPropertyMetadataOptions.AffectsRender,
                                             new PropertyChangedCallback( OnTimeOfDayInvalidated ) ) );
      
        public static readonly DependencyProperty UnfocusedBackgroundProperty =
            DependencyProperty.Register( "UnfocusedBackground", typeof( Brush ), typeof( NumberSpinner ), new PropertyMetadata( null ) );
      
        public static readonly DependencyProperty UnfocusedForegroundProperty =
            DependencyProperty.Register( "UnfocusedForeground", typeof( Brush ), typeof( NumberSpinner ), new PropertyMetadata( null ) );
      
        public static readonly DependencyProperty ValueProperty = 
            DependencyProperty.Register( "Value", typeof( double ), typeof( NumberSpinner ), 
                                             new PropertyMetadata( 0.0, new PropertyChangedCallback( OnValueInvalidated ) ) );
      
        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 double Increment {
            get { return (double) GetValue( IncrementProperty ); }
            set { SetValue( IncrementProperty, value ); }
        }
      
        public string Mask {
            get { return (string) GetValue( MaskProperty ); }
            set { SetValue( MaskProperty, value ); }
        }
      
        public double Maximum {
            get { return (double) GetValue( MaximumProperty ); }
            set { SetValue( MaximumProperty, value ); }
        }
      
        public double Minimum {
            get { return (double) GetValue( MinimumProperty ); }
            set { SetValue( MinimumProperty, 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 double Value {
            get { return (double) GetValue( ValueProperty ); }
            set { SetValue( ValueProperty, value ); }
        }
      
        public NumberSpinner() {
            InitializeComponent();
        }
      
        private void DecrementButton_Click( object sender, RoutedEventArgs e ) {
            Value -= Increment;
        }
      
        private void IncrementButton_Click( object sender, RoutedEventArgs e ) {
            Value += Increment;
        }
      
        private void OnMaximumChanged( double newMaximum ) {
            // Does the control have a Maximum value?
            if ( !double.IsNaN( newMaximum ) ) {
                // It does.  Is the value less than or equal to the maximum?
                if ( Value > newMaximum ) {
                    // It is not.  Set the Value to the newMaximum.
                    Value = newMaximum;
                }
                IncrementButton.IsEnabled = Value < newMaximum;
            }
        }
      
        private static void OnMaximumInvalidated( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
            NumberSpinner spinner = d as NumberSpinner;
            spinner.OnMaximumChanged( (double) e.NewValue );
        }
      
        private void OnMinimumChanged( double newMinimum ) {
            if ( !double.IsNaN( newMinimum ) ) {
                if ( Value < newMinimum ) {
                    Value = newMinimum;
                }
      
                DecrementButton.IsEnabled = Value > newMinimum;
            }
        }
      
        private static void OnMinimumInvalidated( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
            NumberSpinner spinner = d as NumberSpinner;
            spinner.OnMinimumChanged( (double) e.NewValue );
        }
      
        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 ) {
            NumberSpinner spinner = (NumberSpinner) d;
            spinner.OnTimeOfDayModeChanged( (TimesOfDay) e.NewValue );
        }
      
        private void OnValueChanged( double newValue ) {
            if ( ! double.IsNaN( Minimum ) ) {
                if ( newValue < Minimum ) {
                    Value = Minimum;
                }
      
                DecrementButton.IsEnabled = Value > Minimum;
            }
      
            if ( ! double.IsNaN( Maximum ) ) {
                if ( Value > Maximum ) {
                    Value = Maximum;
                }
      
                IncrementButton.IsEnabled = Value < Maximum;
            }
        }
      
        private static void OnValueInvalidated( DependencyObject d, DependencyPropertyChangedEventArgs e ) {
            NumberSpinner spinner = d as NumberSpinner;
            spinner.OnValueChanged( (double) 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;
            }
        }
    }

    Here's some sample xaml showing how I use it on my form:

    <cs:NumberSpinner BorderBrush="{DynamicResource ControlBorder}"
                      FontSize="16"
                      FontWeight="Bold"
                      FocusedBackground="{DynamicResource FocusedBackground}"
                      FocusedForeground="{DynamicResource FocusedForeground}"
                      GridBackground="{DynamicResource ContentBackground}"
                      Grid.Column="3"
                      Grid.Row="13"
                      HorizontalAlignment="Right"
                      Margin="5"
                      Mask="dddddd"
                      Maximum="999999"
                      Minimum="0"
                      x:Name="ResultsLimitBox"
                      TabIndex="12"
                      TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:AdvancedSettingEditor}}}"
                      UnfocusedBackground="{DynamicResource UnfocusedBackground}"
                      UnfocusedForeground="{DynamicResource UnfocusedForeground}"
                      Value="{Binding Path=ResultsLimit, Mode=TwoWay}"
                      VerticalAlignment="Center"
                      Width="200" />

    The images used by the buttons are just an up arrow and a down arrow. 

    Follow these steps:
    1. Place the control into a form and bind its value property to an int.  Set it to some value larger than the minimum.
    2. Run the program. 
    3. Put the cursor in the Masked Numeric Input control.  Type a new value in for the variable.
    4. Press the up button or the down button.  Do not use the up arrow or down arrow on the keyboard!  You should see the value revert back to what it was plus or minus one, depending on which button you pressed.
  5. Tina Stancheva
    Admin
    Tina Stancheva avatar
    3298 posts

    Posted 13 Jun 2012 Link to this post

    Hi Tony,

    Thank you for getting back to us.

    Looking through your code snippet, I noticed that you've defined the Mask using the 'd' token. However, this token represents a required symbol in the MaskedNumeriInput control. This basically means that the value of the control won't be updated until all required positions are filled with a character.

    This is why using your setup, you have to add 6 symbols in the control in order to update its value. Only then you will be able to apply your increment/decrement logic on the new value of the control. You can get over this behavior by setting the RadMaskedNumericInput.AllowInvalidValues property to True. This will make the control update its value even if it isn't valid. But I'd suggest changing your Mask to "#6" instead:
    <cs:NumberSpinner x:Name="ResultsLimitBox"
                         Grid.Row="13"
                         Grid.Column="3"
                         Width="200"
                         Margin="5"
                         HorizontalAlignment="Right"
                         VerticalAlignment="Center"
                         BorderBrush="Blue"
                         FocusedBackground="LightGreen"
                         FocusedForeground="Red"
                         FontSize="16"
                         FontWeight="Bold"
                         GridBackground="LavenderBlush"
                         Mask="#6"
                         Maximum="999999"
                         Minimum="0"
                         TabIndex="12"
                         UnfocusedBackground="LightCoral"
                         UnfocusedForeground="Navy"
                         Value="{Binding Path=ResultsLimit,
                                         Mode=TwoWay}" />

    I attached a sample demonstrating how this will work. Give ti a try and let me know if you need more info.

    Regards,
    Tina Stancheva
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  6. Tony
    Tony avatar
    111 posts
    Member since:
    May 2011

    Posted 13 Jun 2012 Link to this post

    Tina:

    Thank you very much!  That does indeed fix the problem!

    Tony
Back to Top
UI for WPF is Visual Studio 2017 Ready