GridView Integer Column - Rounding

9 posts, 0 answers
  1. Robert
    Robert avatar
    9 posts
    Member since:
    Apr 2011

    Posted 12 Sep 2011 Link to this post

    I have a GridViewDecimalColumn that I'm using to store integers entered by the user.  I set the DataType property equal to GetType(Integer) (I'm using VB.NET).  When a user enters a value such as 24.8, it automatically gets rounded up to 25.  If they enter 24.2, obviously it gets rounded down to 24.  The users shouldn't be entering decimal numbers, but I've heard that they have been and they don't ever want the numbers to round up.

    My question is this:  How can I force the value to always round down, so that 24.8 will be changed to 24?  I know I can use a cell value change event, but I was hoping there was some property in the GridViewDecimalColumn that could be set to handle this.

    Thanks,
    Robert S.
  2. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 13 Sep 2011 Link to this post

    Hello Robert,

    In my point of view there are a few possible approaches:
    First, you should handle the CellEditorInitialized event and set the editor itself to accept just integers (the cleanest way - in my point of view)

    Other way would be to register the the editors element value changed event and handle the value rounding or floor-ing there.

    Or another would be the one you mentioned with the value changed, but i'm not sure that you will be receiving the value non rounded there.

    If you need more help on any of these, just let me know.

    Best Regards,
    Emanuel, Varga
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Robert
    Robert avatar
    9 posts
    Member since:
    Apr 2011

    Posted 13 Sep 2011 Link to this post

    Emanuel,

    I tried as you suggested and looked into using the CellEditorInitialized event to make the editor only accept integers, but I just can't figure out how to do it.  What needs to happen in the CellEditorInitialized event?

    Thanks,
    Robert S.
  5. Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 14 Sep 2011 Link to this post

    Hello Robert,

    You have two options here, sorry for before, i misunderstood and thought that you had decimal places already in the editor...
    C#
    void radGridView1_CellEditorInitialized(object sender, GridViewCellEventArgs e)
    {
        if (e.ActiveEditor is GridSpinEditor)
        {
            var spinEditor = e.ActiveEditor as GridSpinEditor;
            spinEditor.ValueType = typeof(decimal);
            var editorElement = spinEditor.EditorElement as GridSpinEditorElement;
            //ignore all non digit characters on the editor
            editorElement.TextBoxItem.KeyDown += (o, p) =>
                                                     {
                                                         if (!Char.IsDigit((char)p.KeyData))
                                                         {
                                                             p.SuppressKeyPress = true;
                                                             p.Handled = true;
                                                         }
                                                     };
     
            // less clean version, set the value to the cell itself after the edit process has ended
            //var cell = radGridView1.CurrentCell;
            //spinEditor.ValueChanged += (o, p) =>
            //                                {
            //                                    var newValue = Convert.ToDecimal(spinEditor.Value);
            //                                    var value = Math.Floor(newValue);
            //                                    if (value != newValue)
            //                                    {
            //                                        var timer = new Timer();
            //                                        timer.Interval = 20;
            //                                        timer.Tick += (a, b) =>
            //                                                          {
            //                                                              timer.Dispose();
            //                                                              cell.Value = value;
            //                                                          };
            //                                        timer.Enabled = true;
     
            //                                    }
            //                                };
        }
    }

    VB
    Private Sub radGridView1_CellEditorInitialized(sender As Object, e As GridViewCellEventArgs)
        If TypeOf e.ActiveEditor Is GridSpinEditor Then
            Dim spinEditor = TryCast(e.ActiveEditor, GridSpinEditor)
            spinEditor.ValueType = GetType(Decimal)
            Dim editorElement = TryCast(spinEditor.EditorElement, GridSpinEditorElement)
            'ignore all non digit characters on the editor
            editorElement.TextBoxItem.KeyDown += Function(o, p) Do
                If Not [Char].IsDigit(CChar(p.KeyData)) Then
                    p.SuppressKeyPress = True
                    p.Handled = True
                End If
     
                ' less clean version, set the value to the cell itself after the edit process has ended
                'var cell = radGridView1.CurrentCell;
                'spinEditor.ValueChanged += (o, p) =>
                '                                {
                '                                    var newValue = Convert.ToDecimal(spinEditor.Value);
                '                                    var value = Math.Floor(newValue);
                '                                    if (value != newValue)
                '                                    {
                '                                        var timer = new Timer();
                '                                        timer.Interval = 20;
                '                                        timer.Tick += (a, b) =>
                '                                                          {
                '                                                              timer.Dispose();
                '                                                              cell.Value = value;
                '                                                          };
                '                                        timer.Enabled = true;
     
                '                                    }
                '                                };
            End Function
        End If
    End Sub

    Sorry if there are any problems, the conversion to vb is an automatic one. Please don't forget the handles on the event handler.

    Best Regards,
    Emanuel Varga
  6. Alexander
    Admin
    Alexander avatar
    306 posts

    Posted 15 Sep 2011 Link to this post

    Hello Robert,

    Emanuel's solutions handle both your requirements - entering only integer numbers in the editor or rounding down the entered number. You can learn more for the customization options of the RadGridView editors from this and this help articles. Please mark Emanuel's response as an answer if you find it helpful.

    Best regards,
    Alexander
    the Telerik team

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

  7. Robert
    Robert avatar
    9 posts
    Member since:
    Apr 2011

    Posted 15 Sep 2011 Link to this post

    Emanuel,

    I tried implementing your VB code, but I was unsuccessful.  I looked at the first link in Alexander's post and found some success.  I implemented the below code, but I'm having two problems:

    1. If the cell editor is initialized because the user started typing in the cell, the new KeyDown handler isn't called.
    2. If the user types a number from the number pad, it's not recognized as numeric.

    Private Sub radGridView1_CellEditorInitialized(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.GridViewCellEventArgs) Handles radGridView1.CellEditorInitialized
            If EditableIntegerField.Contains(sender.GridViewElement.CurrentColumn.Name) Then
                Dim spinEditor As GridSpinEditor = e.ActiveEditor
                Dim editorElement As GridSpinEditorElement = spinEditor.EditorElement
      
                AddHandler editorElement.KeyDown, AddressOf tbElement_KeyDown
      
            End If
    End Sub
      
    Private Sub tbElement_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
            If Not IsNumeric(ChrW(e.KeyCode)) Then
                e.SuppressKeyPress = True
                e.Handled = True
            End If
    End Sub

    Any help is appreciated.

    Thanks,
    Robert S.
  8. Alexander
    Admin
    Alexander avatar
    306 posts

    Posted 20 Sep 2011 Link to this post

    Hello Robert,

    Thank you for writing back.

    You can handle both number keys and number pad keys using KeyDown event handler like the following one:
    Private Sub tbElement_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
        If (e.KeyValue >= CInt(Keys.NumPad0) AndAlso e.KeyValue <= CInt(Keys.NumPad9)) OrElse _
            (e.KeyValue >= CInt(Keys.D0) AndAlso e.KeyValue <= CInt(Keys.D9)) Then
            Return
        End If
     
        e.SuppressKeyPress = True
        e.Handled = True
    End Sub

    I am unable to reproduce the first issue of this solution. Could you please give us the steps to reproduce it? It will help me find suitable solution for this case.

    I am looking forward to your reply.

    Best regards,
    Alexander
    the Telerik team

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

  9. Robert
    Robert avatar
    9 posts
    Member since:
    Apr 2011

    Posted 28 Sep 2011 Link to this post

    Alexander,

    Thank you for the code for handling number pad input.

    To reproduce the first issue in my last post:
    - In a gridview, click once in a cell that is not already selected.  This selects the cell and has not yet started the cell editor, so the CellEditorInitialized event hasn't fired yet.  Since it hasn't fired yet, the KeyDown event handler isn't registered.
    -Type a single number or any other character into the selected cell.  This fires the CellEditorInitialized  event, and then registers the KeyDown event handler.  Since the KeyDown event already happened (at the beginning of this step), it doesn't get captured by the KeyDown event handler.  Any future key presses will be captured, but that first one isn't handled.

    Would it be possible to use the CurrentCellChanged event to automatically start the cell's editor, which will cause the KeyDown event handler to be registered before the user begins typing?

    Thanks,
    Robert S.
  10. Alexander
    Admin
    Alexander avatar
    306 posts

    Posted 30 Sep 2011 Link to this post

    Hello Robert,

    In general, you can use the CurrentCellChanged event to automatically start cell's editor:
    Private Sub RadGridView1_CurrentCellChanged(ByVal sender As Object, ByVal e As Telerik.WinControls.UI.CurrentCellChangedEventArgs) Handles RadGridView1.CurrentCellChanged
        If e.NewCell IsNot Nothing AndAlso e.NewCell.ColumnInfo.Name = "ColumnName" Then
            Me.RadGridView1.BeginEdit()
        End If
    End Sub

    It will allow you to subscribe to the editor's KeyDown event before the user starts entering data.

    I would not really recommend the above approach because it could change the RadGridView behavior in some cases.

    Despite I was able to follow your scenario for entering values in a cell before subscribing to the editor's KeyDown event, I was not able to input invalid data. Entering a digit works as expected - replaces the current value with the pressed number. Entering non-digit characters opens the editor, but does not input them. The decimal separator is not inputted in my test as well.

    Best regards,
    Alexander
    the Telerik team

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

Back to Top
UI for WinForms is Visual Studio 2017 Ready