RadNumericUpDown not Updating while Focus

2 posts, 1 answers
  1. Johan
    Johan avatar
    3 posts
    Member since:
    Dec 2011

    Posted 03 Apr Link to this post

    Hello I encountered a bug or odd behaviour in the RadNumericUpDown control. I use caliburn micro as a MVVM framework to bind a simple property to the Value of the control. On KeyDown I check the value and if a condition fails, I reset the value to the last valid state.

    The Problem is that the Value is not updated despite the PropertyChanged event firing correctly. The value is updated after the focus is lost.

     

    class ShellViewModel : Screen
    {
        /// <summary>
        /// Value before change
        /// </summary>
        protected double ValueBeforeChange;
     
        private double value;
     
        /// <summary>
        /// Gets or sets the value
        /// </summary>
        public new double Value
        {
            get => value;
            set
            {
                if (!(Math.Abs(value - this.value) > double.Epsilon))
                {
                    return;
                }
     
                Console.WriteLine($"Value changed to {value}");
                this.value = value;
                NotifyOfPropertyChange(() => Value);
            }
        }
     
        public ShellViewModel()
        {
            Value = 10;
            ValueBeforeChange = Value;
        }
     
        public new void KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Return || e.Key == Key.Enter)
            {
                if (Value > 20)
                {
                    Value = ValueBeforeChange;
                }
                else
                {
                    ValueBeforeChange = Value;
                }
            }
        }
    }

     

    <UserControl x:Class="RadUpDownBug.Views.ShellView"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:cal="http://www.caliburnproject.org"
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 mc:Ignorable="d"
                 d:DesignHeight="450" d:DesignWidth="800">
        <StackPanel>
            <telerik:RadNumericUpDown x:Name="Numeric"
                                      FontSize="24"
                                      ValueFormat="Numeric"
                                      NumberDecimalDigits="2"
                                      Value="{Binding Value, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                      ShowButtons="False"
                                      UpdateValueEvent="PropertyChanged"
                                      cal:Message.Attach="[Event KeyDown] = [Action  KeyDown($this,$eventArgs)];" Margin="0" />
            <TextBox></TextBox>
        </StackPanel>
    </UserControl>

     

    So entering a value above 20 and pressing enter should result in the control displaying the last value (10 at the beginning) But it does not. If you click on the TextBox the control is correctly updated.

    Why does this happen and how do I fix this?

  2. Answer
    Dinko
    Admin
    Dinko avatar
    1183 posts

    Posted 08 Apr Link to this post

    Hello Johan,

    Thank you for the provided code snippets.

    I was able to reproduce this behavior on my side using the provided information. Indeed this is strange behavior as you need to click enter twice to update the value. It seems that the reason comes from the Caliburn.Micro assemblies. What I can suggest is to use our build-in EventToCommandBehavior. This way you can bind the KeyDown event to an ICommand from your ViewModel and update the value. I have modified the code snippet and it is working as expected. Check it out:

    <StackPanel>
        <telerik:RadNumericUpDown x:Name="Numeric"
                                FontSize="24"
                                ValueFormat="Numeric" PreviewKeyDown="Numeric_PreviewKeyDown"
                                NumberDecimalDigits="2"
                                UpdateValueEvent="PropertyChanged"
                                UpdateValueToMatchTextOnLostFocus="False" 
                                Value="{Binding Value, Mode=TwoWay}"
                                ShowButtons="False"                                 
                                Margin="0" >
            <telerik:EventToCommandBehavior.EventBindings>
                <telerik:EventBinding Command="{Binding KeyDownCommand}" EventName="KeyDown" PassEventArgsToCommand="True"/>
            </telerik:EventToCommandBehavior.EventBindings>
        </telerik:RadNumericUpDown>            
        <TextBox VerticalAlignment="Center" Width="200"/>
    </StackPanel>

    publicclassShellViewModel : Screen { protecteddouble ValueBeforeChange; privatedouble _value; publicdouble Value { get => _value; set { if (!(Math.Abs(value - this._value) > double.Epsilon)) { return; } Console.WriteLine($"Value changed to {value}"); this._value = value; NotifyOfPropertyChange(() => Value); } } public ICommand KeyDownCommand { get; set; }public ShellViewModel() { Value = 10; ValueBeforeChange = Value; KeyDownCommand = new DelegateCommand(OnCommandExecuted); } private void OnCommandExecuted(object obj) { KeyEventArgs e = obj as KeyEventArgs;

    if (e.Key == Key.Return || e.Key == Key.Enter) { if (Value > 20) { Value = ValueBeforeChange; NotifyOfPropertyChange(() => Value); } else { ValueBeforeChange = Value; } } } }

     

    Regards,
    Dinko
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
Back to Top