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

Set the focus to an element in a custom cell editor

6 Answers 203 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Christoph
Top achievements
Rank 1
Christoph asked on 20 Jul 2011, 05:01 PM
Hi,
I have a custom cell editor that contains a TextBox and a Button. The user can edit the text directly or press the button to display a dialog. Using the examples I found I could implement nearly everthing but one thing is missing:
When editing starts I would like to set the focus to the TextBox in theeditor and select the contained text, so that the user can start typing immediately. Just the behaviour of the normal GridViewTextBoxColumn. In my editor an extra click is required to start typing. The call to Focus() seems to have no effect.

Thanks in advance
Christoph

(Using Q2 2011 on .NET 3.5)

This is what I did:

My custom GridViewDataColumn:
public class IntelliBoxColumn : GridViewDataColumn
{
    public IntelliBoxColumn(string columnName) : base(columnName) { }
 
    public override Type GetDefaultEditorType()
    {
        return typeof(IntelliBoxGridEditor);
    }
 
    public override Type GetCellType(GridViewRowInfo row)
    {
        if (row is GridViewDataRowInfo)
        {
            return typeof(IntelliBoxCellElement);
        }
        return base.GetCellType(row);
    }
}

My custom EditorElement:
public partial class IntelliBoxEditorElement : LightVisualElement
{
 
    RadTextBoxItem textBox;
    RadButtonElement button;
 
    public RadTextBoxItem TextBox { get { return this.textBox;}}
 
    public RadButtonElement Button { get { return this.button; } }
 
    protected override void CreateChildElements()
    {
        textBox = new RadTextBoxItem();
        textBox.RouteMessages = true;
        button = new RadButtonElement("...");
        button.Padding = new Padding(2, 0, 2, 0);
        this.Children.Add(textBox);
        this.Children.Add(button);
    }
 
    protected override SizeF ArrangeOverride(SizeF finalSize)
    {
        RectangleF clientRect = GetClientRectangle(finalSize);
        RectangleF buttonRect = new RectangleF(clientRect.Right - button.DesiredSize.Width, clientRect.Top,
            button.DesiredSize.Width, clientRect.Height);
        RectangleF textRect = new RectangleF(clientRect.Left, clientRect.Top + (clientRect.Height - textBox.DesiredSize.Height) / 2,
            buttonRect.Left - clientRect.Left - 2, textBox.DesiredSize.Height);
 
        foreach (RadElement element in this.Children)
        {
            if (element == this.textBox)
            {
                element.Arrange(textRect);
            }
            else if (element == this.button)
            {
                element.Arrange(buttonRect);
            }
            else
            {
                ArrangeElement(element, finalSize);
            }
        }
        return finalSize;
    }
 
}

My custom GridEditor:
I try to set the focus in BeginEdit() but this has no effect.

public class IntelliBoxGridEditor : BaseGridEditor
{
    private bool endEditOnLostFocus = false;
 
    protected override Telerik.WinControls.RadElement CreateEditorElement()
    {
        return new IntelliBoxEditorElement();
    }
 
    private IntelliBoxEditorElement IntelliBox
    {
        get { return (IntelliBoxEditorElement)EditorElement; }
    }
 
    public override bool EndEditOnLostFocus
    {
        get { return endEditOnLostFocus; }
    }
 
    public override object Value
    {
        get { return IntelliBox.Text;}
        set
        {
            string strValue = string.Empty;
            if (value != null && value != DBNull.Value) strValue = value.ToString();
            IntelliBox.TextBox.Text = strValue;
        }
    }
 
    public override Type DataType
    {
        get { return typeof(string);}
    }
 
    public override void BeginEdit()
    {
        base.BeginEdit();
        IntelliBox.TextBox.TextChanging += new TextChangingEventHandler(TextBox_TextChanging);
        IntelliBox.TextBox.TextChanged += new EventHandler(TextBox_TextChanged);
        IntelliBox.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown);
        IntelliBox.Button.Click += new EventHandler(Button_Click);
        IntelliBox.TextBox.SelectAll();
        IntelliBox.TextBox.Focus();
    }
 
    public override bool EndEdit()
    {
        IntelliBox.TextBox.TextChanging -= new TextChangingEventHandler(TextBox_TextChanging);
        IntelliBox.TextBox.TextChanged -= new EventHandler(TextBox_TextChanged);
        IntelliBox.TextBox.KeyDown -= new KeyEventHandler(TextBox_KeyDown);
        IntelliBox.Button.Click -= new EventHandler(Button_Click);
        return base.EndEdit();
    }
 
    void TextBox_TextChanging(object sender, TextChangingEventArgs e)
    {
        ValueChangingEventArgs args = new ValueChangingEventArgs(e.NewValue);
        args.OldValue = e.OldValue;
        OnValueChanging(args);
        e.Cancel = args.Cancel;
    }
 
    void TextBox_TextChanged(object sender, EventArgs e)
    {
        OnValueChanged();
    }
 
    void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        RadGridView grid = ((RadElement)sender).ElementTree.Control as RadGridView;
        if (grid != null)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                case Keys.Enter:
                case Keys.Up:
                case Keys.Down:
                    grid.GridBehavior.ProcessKeyDown(e);
                    break;
            }
        }
    }
 
    void Button_Click(object sender, EventArgs e)
    {
        endEditOnLostFocus = false;
        var gridView = (WPDataGrid)IntelliBox.ElementTree.Control;
        gridView.RaiseButtonClicked(this);
        endEditOnLostFocus = true;
        gridView.EndEdit();
    }
 
}


My custom GridDataCellElement:
(The puspose of this cell-element is to start editing as soon as cell becomes current. I did not manage to get this behaviour by setting BeginEditMode)
public class IntelliBoxCellElement : GridDataCellElement
{
    private RadLabelElement _label;
 
    private IntelliBoxColumn _column;
    private GridRowElement _row;
 
    public IntelliBoxCellElement(GridViewColumn column, GridRowElement row)
        : base(column, row)
    {
        this.BackColor = Color.White;
    }
 
    private bool _wasCurrent;
 
    public override bool IsCurrent
    {
        get return base.IsCurrent; }
        set
        {
            base.IsCurrent = value;
            if (value && value != _wasCurrent)
                _row.RowInfo.Cells[_column.Name].BeginEdit();
 
            _wasCurrent = value;
        }
    }
 
    protected override Type ThemeEffectiveType { get {return typeof(GridDataCellElement); } }
 
    public override void Initialize(GridViewColumn column, GridRowElement row)
    {
        _column = (IntelliBoxColumn)column;
        _row = row;
        base.Initialize(column, row);
    }
 
    protected override void CreateChildElements()
    {
        _label = new RadLabelElement();
        _label.Margin = new Padding(2, 2, 2, 2);
        _label.LabelText.AutoEllipsis = true;
        _label.LabelText.AutoSize = true;
        _label.LabelText.AutoSizeMode = RadAutoSizeMode.Auto;
        _label.LabelText.TextWrap = false;
        this.Children.Add(_label);
    }
 
    protected override void DisposeManagedResources()
    {
        base.DisposeManagedResources();
    }
 
    protected override void SetContentCore(object value)
    {
        if (value != null)
        {
            _label.Text = value.ToString();
        }
    }
 
    public override bool IsCompatible(GridViewColumn data, object context)
    {
        return data is IntelliBoxColumn && context is GridDataRowElement;
    }
}


6 Answers, 1 is accepted

Sort by
0
Accepted
Martin Vasilev
Telerik team
answered on 25 Jul 2011, 05:10 PM
Hi Christoph,

Thank you for writing.

In order to achieve the desired behaviour of your custom editor, I would make the following changes in your code:

1. Use RadTextBoxElement instead RadTextBoxItem in IntelliBoxEditorElement:
public class IntelliBoxEditorElement : LightVisualElement
    {
        RadTextBoxElement textBox;
        //RadTextBoxItem textBox;
        RadButtonElement button;
 
        //public RadTextBoxItem TextBox { get { return this.textBox; } }
        public RadTextBoxElement TextBox { get { return this.textBox; } }
 
        public RadButtonElement Button { get { return this.button; } }
 
        protected override void CreateChildElements()
        {
            textBox = new RadTextBoxElement(); //new RadTextBoxItem();
            textBox.TextBoxItem.RouteMessages = true; //.RouteMessages = true;
            button = new RadButtonElement("...");
            button.Padding = new Padding(2, 0, 2, 0);
            this.Children.Add(textBox);
            this.Children.Add(button);
        }
 
        protected override SizeF ArrangeOverride(SizeF finalSize)
        {
            RectangleF clientRect = GetClientRectangle(finalSize);
            RectangleF buttonRect = new RectangleF(clientRect.Right - button.DesiredSize.Width, clientRect.Top,
                button.DesiredSize.Width, clientRect.Height);
            RectangleF textRect = new RectangleF(clientRect.Left, clientRect.Top + (clientRect.Height - textBox.DesiredSize.Height) / 2,
                buttonRect.Left - clientRect.Left - 2, textBox.DesiredSize.Height);
 
            foreach (RadElement element in this.Children)
            {
                if (element == this.textBox)
                {
                    element.Arrange(textRect);
                }
                else if (element == this.button)
                {
                    element.Arrange(buttonRect);
                }
                else
                {
                    ArrangeElement(element, finalSize);
                }
            }
            return finalSize;
        }
 
    }

2. Call SelectedAll of RadTextBoxItem and Focus of the hosted text box control in the IntelliBoxGridEditor's BeginEdit method:
public override void BeginEdit()
{
    base.BeginEdit();
    IntelliBox.TextBox.TextChanging += new TextChangingEventHandler(TextBox_TextChanging);
    IntelliBox.TextBox.TextChanged += new EventHandler(TextBox_TextChanged);
    IntelliBox.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown);
    IntelliBox.Button.Click += new EventHandler(Button_Click);
     
    IntelliBox.TextBox.TextBoxItem.SelectAll();
    IntelliBox.TextBox.TextBoxItem.HostedControl.Focus();
 
    //IntelliBox.TextBox.SelectAll();
    //IntelliBox.TextBox.Focus();
}

Hope this helps. Let me know if you need additional assistance.

Greetings,
Martin Vasilev
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Christoph
Top achievements
Rank 1
answered on 26 Jul 2011, 09:15 AM
Hi Martin,

That's it. Thank you!

Regards, Christoph
0
Pairat
Top achievements
Rank 1
answered on 28 Aug 2011, 03:35 AM
Hi Martin,

I am new to telerlik components. I am evaluating radgridview. Could you please post the complete project of this textbox and button sample?

Thank you.

Pairat
0
Stefan
Telerik team
answered on 01 Sep 2011, 09:03 AM
Hello Pairat,

Thank you for writing.

Please refer to the attached project, where I have accumulated the code posted above.

Should you have any other questions, do not hesitate to contact us.
 
Kind regards,
Stefan
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

0
Pairat
Top achievements
Rank 1
answered on 01 Sep 2011, 12:39 PM
Hi Stafan,

Thank you for the sample.

Best regards,

Pairat
0
Stefan
Telerik team
answered on 02 Sep 2011, 02:10 PM
Hi Pairat,

I am glad that I could help. If you have any other questions, do not hesitate to contact us.

Regards,
Stefan
the Telerik team

Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>

Tags
GridView
Asked by
Christoph
Top achievements
Rank 1
Answers by
Martin Vasilev
Telerik team
Christoph
Top achievements
Rank 1
Pairat
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or