RadNumericUpDown keyboard focus problems with its internal edit control

4 posts, 0 answers
  1. Joe
    Joe avatar
    59 posts
    Member since:
    Nov 2017

    Posted 06 Dec 2018 Link to this post

    I use RadNumericUpDown in many places.  My application runs on a PC and on the Microsoft Surface and uses the Windows8Touch theme. 
     
    My problem is that whenever the user clicks the + or - button of a RadNumericUpDown the edit control receives keyboard focus which I do not want and cannot seem to prevent.  Why is this a problem?  Because on the MS Surface, this causes the Windows Virtual Keyboard to appear, immediately obscuring the very control the user is using.  The user isn't trying to edit the text box, mind you, just tapping the buttons.

    If the the user is only tapping the buttons, it seems that the edit box should not get focus.  That should not happen until you actually try to *type* in it.   But even if you think it *should* get focus, there at least needs to be a way to prevent it from happening.  Yet I cannot find any way short of completely retemplating the control.
     
    Here is what I tried:

    1. I tried to setting the entire RadNumericControl's IsEditable property to "False" but this has no effect.  Even though the user cannot edit the box, clicking the '+' or '-' button *still* makes the edit control think it is being edited enough to give it focus and force that virtual keyboard to appear

    2. Then I tried setting the entire control's "Focusable" property to "False" but that didn't work either.  The internal edit control still gets keyboard focus.  This is because the Telerik template for the control fails to pass the "Focusable" to its internal edit through TemplateBinding. 

    The only way I've managed to "fix" this is by completely copying the entire RadNumericUpDown control's template and making it pass "Focusable" to its internal edit via the TemplateBinding.  Then I use this template for my RadNumericUpDown and set its Focusable property to false.

    But this is serious  overkill and my copied template is not using the Telerik Windows8Touch theme that I applied to everything else.  So it looks out of place and terrible.  It appears I can copy a whole bunch of stuff from the Telerik-installed XAML for that theme, but that's even more overkill than before. 

    So my questions are these:

    1. Am I missing some simpler method here?  Does RadNumericUpDown give me a way to get at the internal edit control and prevent it from getting keyboard focus short of copying its entire template?  

    2. Also, am I correct that it's internal edit should NOT get keyboard focus if you just tap the buttons (at least if it's not editable)?

    I am hoping you can point me to an easier way.  

  2. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2216 posts

    Posted 11 Dec 2018 Link to this post

    Hello Joe,

    Indeed, the control's input box gets the focus when you click on the buttons. In matter of fact it revives the focus regardless where on the control you click. This happens manually in the source code of the RadNumericUpDown control. And I am afraid that at this point this cannot be altered. Even re-templating the control won't do the work because the Focus() method of the input TextBox is called in code on few occasions.

    The easiest way to acheive your requirement is to hide the up and down buttons with the ShowButtons property of the control. And then manually define two RepeatButtons. On click of each button you can increase or decrease the value of the control, via its Value property.

    Regards,
    Martin Ivanov
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Joe
    Joe avatar
    59 posts
    Member since:
    Nov 2017

    Posted 11 Dec 2018 in reply to Martin Ivanov Link to this post

    Hi Martin,

    I appreciate your time.  However I think you are mistaken here.  re-templating the control really does work  I've verified it.  

    Once you set any control's Focusable property to "false", you can then call Focus() on it to your heart's content.  It won't do a thing.  Focusable overrides the attempt. 

    That's all I'm saying.  Telerik needn't change their code.  They should simply add the one single TemplateBinding for Focusable -- passing that "Focusable" of the whole control to the inner TextBox -- and it will work.  

    Philosophically speaking I believe that is how a user would *expect* it work.

    To be really pedantic, I've included my altered XAML for it at the bottom of this message.   Not that you need it to get my point.

    Literally I copied the "RadNumericUpDownControlTemplate" from Telerik's XAML (for my Windows8Touch theme) into my application and added just the one single TemplateBinding in the TextBox Section of the template.


    <ControlTemplate x:Key="RadNumericUpDownControlTemplate" TargetType="{x:Type tk:RadNumericUpDown}">
        <Grid>
     
           ... removed unchanged XAML.   Relevant change is below in "textbox" where I added the "Focusable" templatebinding...
     
            <TextBox x:Name="textbox"
                    Grid.Column="1"
                    IsReadOnly="{TemplateBinding IsReadOnly}"
                    TabIndex="{TemplateBinding TabIndex}"
                    BorderThickness="0"
                    Padding="{TemplateBinding Padding}"
                    Background="{TemplateBinding Background}"
                    Foreground="{TemplateBinding Foreground}"
                    FontFamily="{TemplateBinding FontFamily}"
                    FontSize="{TemplateBinding FontSize}"
                    VerticalAlignment="Stretch"
                    Focusable="{TemplateBinding Focusable}"
                    HorizontalContentAlignment="Stretch"
                    TextAlignment="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=HorizontalContentAlignment, Converter={StaticResource HorizontalContentAlignmentToTextAlignmentConverter}}"
                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">






  4. Martin Ivanov
    Admin
    Martin Ivanov avatar
    2216 posts

    Posted 12 Dec 2018 Link to this post

    Hey Joe,

    Thanks for sharing the additional information and your code. You are right, my re-templating statement wasn't right. That is my bad. Please excuse me for this.

    About the Focusable, I am not sure that there is a need of such property and if it is going to bring any benefit to the developer that uses the control. This will allow you to manually control the focus ability of the control, but it won't help you directly. You will still need to maintain the Focusable state because probably you will want to focus the TextBox when you click on it. Instead, we can consider to add something like a focus mode that decides when the focus should be taken from the TextBox. For example, there could be two modes - "take the focus when you click only on the TextBox" and "take the focus when you click on the TextBox or the buttons". Please tell me if this sounds reasonable to you.

    As for a bit more convenient approach for your case, you can create a custom numeric up/down control that derives from RadNumericUpDown. And there (in code) you can get the TextBox and bind its Focusable property to a new property defined in the custom control. Here is an example in code:
    public class CustomNumericUpDown : RadNumericUpDown
    {
        public bool IsInputFocusable
        {
            get { return (bool)GetValue(IsInputFocusableProperty); }
            set { SetValue(IsInputFocusableProperty, value); }
        }
                 
        public static readonly DependencyProperty IsInputFocusableProperty =
            DependencyProperty.Register(
                "IsInputFocusable",
                typeof(bool),
                typeof(CustomNumericUpDown),
                new PropertyMetadata(true));
     
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
     
            var textBox = (TextBox)this.GetTemplateChild("textbox");
            var focusableBinding = new Binding("IsInputFocusable") { Source = this };
            textBox.SetBinding(TextBox.FocusableProperty, focusableBinding);
        }
    }
    And here you can see how is used in XAML.
    <local:CustomNumericUpDown IsInputFocusable="False"/>

    I also attached a project showing a modified version of the custom control that allows you to focus the TextBox only on click on it. I hope this helps.

    Regards,
    Martin Ivanov
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top