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

How can focus to custom cell element in CellBeginEdit event?

7 Answers 266 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Reza
Top achievements
Rank 1
Reza asked on 29 May 2018, 10:16 AM

Hi everyone

I put a RadGridView in Form with enabled its edit mode (AllowEditRow = true), and has "id" and "name" columns, and three rows of data. Also I created a custom user control that has a TextBox and a Button (named it ccTest). Then I choose a cell from "name" column and any row at run time. Now I start to type letters from keyboard. In this case, I bring up the custom user control.

The problem is: The typed letters don't show in custom user control, because it's TextBox not focused yet. Therefore I must click one more time to focus it, before start type letters.

Question is: How can I focus the TextBox of custom user control when it appear from CellBeginEdit event?

Microsoft Visual Studio 2017 (C# language) installed on Windows 10  -  Telerik WinForms 2017 R3 SP1 (2017.3.1017.40).

-------------------------------------------

ccTest.Designer.cs:

namespace TestGridFocus
{
    partial class ccTest
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Component Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            //
            // textBox1
            //
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.textBox1.Location = new System.Drawing.Point(0, 0);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(92, 20);
            this.textBox1.TabIndex = 0;
            //
            // button1
            //
            this.button1.Dock = System.Windows.Forms.DockStyle.Right;
            this.button1.Location = new System.Drawing.Point(92, 0);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(28, 20);
            this.button1.TabIndex = 1;
            this.button1.Text = "?";
            this.button1.UseVisualStyleBackColor = true;
            //
            // ccTest
            //
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button1);
            this.Name = "ccTest";
            this.Size = new System.Drawing.Size(120, 20);
            this.ResumeLayout(false);
            this.PerformLayout();
 
        }
 
        #endregion
 
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Button button1;
    }
}

 

ccTest.cs:

using System.Windows.Forms;
 
namespace TestGridFocus
{
    public partial class ccTest : UserControl
    {
        public ccTest()
        {
            InitializeComponent();
        }
 
        public string Value
        {
            get
            {
                return textBox1.Text;
            }
            set
            {
                textBox1.Text = value;
            }
        }
    }
}

Form1.Designer.cs:

namespace TestGridFocus
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows Form Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn1 = new Telerik.WinControls.UI.GridViewDecimalColumn();
            Telerik.WinControls.UI.GridViewTextBoxColumn gridViewTextBoxColumn1 = new Telerik.WinControls.UI.GridViewTextBoxColumn();
            Telerik.WinControls.UI.GridViewDecimalColumn gridViewDecimalColumn2 = new Telerik.WinControls.UI.GridViewDecimalColumn();
            Telerik.WinControls.UI.TableViewDefinition tableViewDefinition1 = new Telerik.WinControls.UI.TableViewDefinition();
            this.radGridView1 = new Telerik.WinControls.UI.RadGridView();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1.MasterTemplate)).BeginInit();
            this.SuspendLayout();
            //
            // radGridView1
            //
            this.radGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
            | System.Windows.Forms.AnchorStyles.Left)
            | System.Windows.Forms.AnchorStyles.Right)));
            this.radGridView1.Location = new System.Drawing.Point(12, 12);
            //
            //
            //
            this.radGridView1.MasterTemplate.AllowAddNewRow = false;
            gridViewDecimalColumn1.FieldName = "id";
            gridViewDecimalColumn1.HeaderText = "id";
            gridViewDecimalColumn1.Name = "id";
            gridViewDecimalColumn1.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            gridViewTextBoxColumn1.FieldName = "name";
            gridViewTextBoxColumn1.HeaderText = "name";
            gridViewTextBoxColumn1.Name = "name";
            gridViewTextBoxColumn1.Width = 150;
            gridViewDecimalColumn2.FieldName = "age";
            gridViewDecimalColumn2.HeaderText = "age";
            gridViewDecimalColumn2.Name = "age";
            gridViewDecimalColumn2.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            this.radGridView1.MasterTemplate.Columns.AddRange(new Telerik.WinControls.UI.GridViewDataColumn[] {
            gridViewDecimalColumn1,
            gridViewTextBoxColumn1,
            gridViewDecimalColumn2});
            this.radGridView1.MasterTemplate.ViewDefinition = tableViewDefinition1;
            this.radGridView1.Name = "radGridView1";
            this.radGridView1.Size = new System.Drawing.Size(270, 237);
            this.radGridView1.TabIndex = 0;
            this.radGridView1.Text = "radGridView1";
            this.radGridView1.CellBeginEdit += new Telerik.WinControls.UI.GridViewCellCancelEventHandler(this.radGridView1_CellBeginEdit);
            this.radGridView1.CellEndEdit += new Telerik.WinControls.UI.GridViewCellEventHandler(this.radGridView1_CellEndEdit);
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(294, 261);
            this.Controls.Add(this.radGridView1);
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1.MasterTemplate)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).EndInit();
            this.ResumeLayout(false);
 
        }
 
        #endregion
 
        private Telerik.WinControls.UI.RadGridView radGridView1;
    }
}

 

Form1.cs:

using System;
using System.Data;
using System.Windows.Forms;
using Telerik.WinControls;
 
namespace TestGridFocus
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private DataTable GetData()
        {
            DataTable dt = new DataTable();
 
            dt.Columns.Add("id", typeof(int));
            dt.Columns.Add("name", typeof(string));
 
            dt.Rows.Add(1, "Jack");
            dt.Rows.Add(2, "Joe");
            dt.Rows.Add(3, "Bob");
 
            dt.AcceptChanges();
 
            return dt;
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            radGridView1.DataSource = GetData();
        }
 
        ccTest test = new ccTest();
 
        private void radGridView1_CellBeginEdit(object sender, Telerik.WinControls.UI.GridViewCellCancelEventArgs e)
        {
            if (e.Column == radGridView1.Columns["name"])
            {
                RadHostItem item = new RadHostItem(test);
 
                test.Value = e.Row.Cells[e.ColumnIndex].Value.ToString();
                radGridView1.CurrentCell.Children.Add(item);
                item.HostedControl.Focus();
            }
        }
 
        private void radGridView1_CellEndEdit(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
        {
            if (e.Column == radGridView1.Columns["name"])
            {
                e.Row.Cells[e.ColumnIndex].Value = test.Value;
                radGridView1.CurrentCell.Children.RemoveAt(0);
            }
        }
    }
}

 

7 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 30 May 2018, 05:57 AM
Hello, Reza,    

According to the provided code snippet, I don't think that you have chosen the most appropriate approach to embed a form in a RadHostItem inside a cell element. That is why I would recommend you to have a look at the following KB article which demonstrates a quite useful approach for updating cell values: https://www.telerik.com/support/kb/winforms/details/create-pop-up-user-control-for-row-editing

I hope this information helps. If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Reza
Top achievements
Rank 1
answered on 30 May 2018, 07:48 AM

Hi Dess,

Thanks for your reply.

Please note that, I embedded an inherited custom control (ccTest) from System.Windows.Forms.UserControl into RadHostItem.

Also, I saw your linked article a few days ago. But I don't want a panel for data entry on grid. I want do data entry exactly into grid cell by focusing on ccTest after start cell edit mode.

-------------------

Detailed information by pictures:

Picture 1: I select a cell on grid from "name" column.

Picture 2: I type a character and cell go to the edit mode. But ccTest is not focused at now, and the object behind it is focused.

Picture 3: I must click on ccTest to set focus on it, and this is my problem.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 31 May 2018, 06:18 AM
Hello, Reza,  

Note that you should cancel entering edit mode in RadGridView because the default editor will get the focus. It is also necessary to focus the TextBox inside the UserControl. Here is the modified code snippet where the 1st child control is the TextBox itself: 
ccTest test = new ccTest();
 
private void radGridView1_CellBeginEdit(object sender, Telerik.WinControls.UI.GridViewCellCancelEventArgs e)
{
    if (e.Column == radGridView1.Columns["name"])
    {
        RadHostItem item = new RadHostItem(test);
 
        test.Value = e.Row.Cells[e.ColumnIndex].Value.ToString();
        radGridView1.CurrentCell.Children.Add(item);
        test.Controls[1].Focus();
         
        e.Cancel = true;
    }
}

I would recommend you  to have a look at the custom editors approach demonstrated in the following help article. Thus, you can construct a custom editor according to your custom requirement and activate it when entering edit mode for this particular cell: https://docs.telerik.com/devtools/winforms/gridview/editors/using-custom-editors

I hope this information helps. If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Reza
Top achievements
Rank 1
answered on 01 Jun 2018, 09:10 AM

Hi Dess,

Your suggestion is very excellent, and it solved my focus problem.

-----------------

But, another problem was created for me, after added above line of code:

1- You consider that I am in edit mode into ccTest and changed it's value. Now I press the TAB key (note that: for prevent button focusing, I changed the TabStop property of ccTest's button to False). At this time the CellEndEdit event not fired. Even though the current cell changed to next cell, but the ccTest is active/display yet, and any typed character put on it.

-----------------

The another problem is:

2- If I choose the cell from "name" column by mouse, and type any characters, the first typed character consume for set cell in edit mode. For example if I type the "alexander", the "a" character used to set cell in edit mode and the remaining characters ("lexander") put on ccTest. How can I prevent it?

 ----------------

Also, I refer to your suggested link. I could not use it, because it inherited from a Telerik element object (for example: RadTrackBarElement). I have the many custom controls that inherited from .NET UserControl.

 

Special thanks for your replies.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 01 Jun 2018, 11:20 AM
Hello, Reza,  

In the specific project you have a text box and a button. It is possible to use a RadButtonElement and a RadTextBoxElement inside a custom editor and achieve the same behavior as now. In addition, the Tab key problem won't occur. As to the first pressed key, it has a special handling in the row behavior which is responsible to keyboard and mouse handling. Here is the modified code snippet. You can find updated the sample project as well.

public RadForm1()
{
    InitializeComponent();
 
    this.radGridView1.EditorRequired += radGridView1_EditorRequired;
 
    BaseGridBehavior gridBehavior = radGridView1.GridBehavior as BaseGridBehavior;
    gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
    gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new CustomGridDataRowBehavior());
}


private void radGridView1_EditorRequired(object sender, EditorRequiredEventArgs e)
{
    if (this.radGridView1.CurrentColumn.Name == "name")
    {
        e.Editor = new MyEditor();
    }
}


public class MyEditor : BaseGridEditor
{
    protected override RadElement CreateEditorElement()
    {
        return new MyEditorElement();
    }
 
    public override object Value
    {
        get
        {
            MyEditorElement element = (MyEditorElement)this.EditorElement;
            return element.TextBox.Text;
        }
        set
        {
            MyEditorElement element = (MyEditorElement)this.EditorElement;
            element.TextBox.Text = value + "";
        }
    }
 
    public override void BeginEdit()
    {
        base.BeginEdit();
        MyEditorElement element = (MyEditorElement)this.EditorElement;
        element.TextBox.TextChanged += TextBox_TextChanged;
        element.TextBox.Focus();
    }
 
    public override bool EndEdit()
    {
        MyEditorElement element = (MyEditorElement)this.EditorElement;
        element.TextBox.TextChanged -= TextBox_TextChanged;
        return base.EndEdit();
    }
 
    private void TextBox_TextChanged(object sender, EventArgs e)
    {
        OnValueChanged();
    }
}
 
public class MyEditorElement : RadEditorElement
{
    StackLayoutElement container = new StackLayoutElement();
    RadTextBoxElement textbox = new RadTextBoxElement();
    RadButtonElement button = new RadButtonElement();
 
    public RadTextBoxElement TextBox
    {
        get
        {
            return this.textbox;
        }
    }
 
    public RadButtonElement Button
    {
        get
        {
            return this.button;
        }
    }
 
    protected override void CreateChildElements()
    {
        base.CreateChildElements();
        container.Orientation = Orientation.Horizontal;
        container.StretchHorizontally = true;
        this.Children.Add(container);
        container.Children.Add(textbox);
        button.Text = "Click";
        button.StretchHorizontally = false;
        button.Click += button_Click;
        container.Children.Add(button);
    }
 
    private void button_Click(object sender, EventArgs e)
    {
        RadMessageBox.Show("Clicked!");
    }
}
 
public class CustomGridDataRowBehavior : GridDataRowBehavior
{
    protected override bool ProcessAlphaNumericKey(KeyPressEventArgs keys)
    {
        bool result = base.ProcessAlphaNumericKey(keys);
        if (this.GridViewElement.ActiveEditor is MyEditor)
        {
            this.GridViewElement.ActiveEditor.Value = keys.KeyChar;
            if (this.GridViewElement.IsInEditMode)
            {
                MyEditor textBox = (MyEditor)this.GridViewElement.ActiveEditor;
                RadTextBoxItem textBoxItem = ((MyEditorElement)textBox.EditorElement).TextBox.TextBoxItem;
                textBoxItem.SelectionStart = 1;
                textBoxItem.SelectionLength = 0;
            }
 
            return true;
        }
        return result;
    }
}

I hope this information helps. If you have any additional questions, please let me know. 

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Reza
Top achievements
Rank 1
answered on 02 Jun 2018, 12:02 PM

Hi Dess,

Special thanks for your patience and replies.

I made a little change in your MyEditorElement source code, to work with ccTest and RadHostItem instead of the RadTextBoxElement, RadButtonElement and StackLayoutElement. Because I work on a big team solution with many complex custom controls, and It is not possible to rewrite them by Rad objects. Therefore I had to use .NET UserControl in RadGridView cell edit mode.

At now, my problem SOLVED completely.

Best regards - Reza

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 04 Jun 2018, 08:17 AM
Hello, Reza,  

I am glad that the code snippet from my previous post was suitable for achieving your custom requirement. For any further inquiries I would recommend you to submit a support ticket where the Telerik support will gladly assist you according to your license. Thank you for your understanding.

Regards,
Dess
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
GridView
Asked by
Reza
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Reza
Top achievements
Rank 1
Share this question
or