This is a migrated thread and some comments may be shown as answers.

RadNumericUpDown not Updating while Focus

1 Answer 563 Views
MaskedInput (Numeric, DateTime, Text, Currency)
This is a migrated thread and some comments may be shown as answers.
Johan
Top achievements
Rank 1
Johan asked on 03 Apr 2020, 08:23 AM

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?

1 Answer, 1 is accepted

Sort by
0
Accepted
Dinko | Tech Support Engineer
Telerik team
answered on 08 Apr 2020, 06:37 AM

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.
Tags
MaskedInput (Numeric, DateTime, Text, Currency)
Asked by
Johan
Top achievements
Rank 1
Answers by
Dinko | Tech Support Engineer
Telerik team
Share this question
or