1

I'm wondering how you can set the selected element of a gridviewcomboboxcolumn.

As a bit of a foreword: I'm using the column with autocomplete mode in order to have autocomplete functionality, but I also want to add new elements to the list. It worked so far without a hitch EXCEPT for one situation:

I already have:

T1
T12
T123

In the data source.

Then when I have for example T12 selected and do backspace to select T1 I've got the problem that I need to manually click on T1 in the list AS there is no selection of T1 as there are multiple possibilities shown. Thus when I leave the editor mode without manually selecting T1 I get T12 as selected item.

I want to change this behaviour in such a way that the first found item is pre selected (always). (regardless if it is a new element or a changed to element so to say)

Currently I've already added a custom handler for the cellendedit to add the new value to the list:

private void MainFormGridView_CellEndEdit(object Sender, GridViewCellEventArgs eventArgs)
{
    var virtualizedCurrentCell = ((Telerik.WinControls.UI.GridVirtualizedCellElement)(currentCell));
    var currentGridviewComboBoxColumn = ((Telerik.WinControls.UI.GridViewComboBoxColumn)(virtualizedCurrentCell.Data));
    if (((List<string>)currentGridviewComboBoxColumn.DataSource).IndexOf((string)currentCell.Value) > -1)
    {
        foundValueInList = true;
    }
    if (!foundValueInList)
    {
        ((List<string>)currentGridviewComboBoxColumn.DataSource).Add((string)currentCell.Value);
    }

}

The column itself is created in this way (bnefore being added to the gridview it is a part of:

GridViewComboBoxColumn newColumn;
newColumn = new GridViewComboBoxColumn();
((GridViewComboBoxColumn)newColumn).DataSource = (from c in entity.myOffer
                                                  orderby c.customer
                                                  where c.customer!= null
                                                  select c.customer)
                                                    .Distinct()
                                                    .ToList();
((GridViewComboBoxColumn)newColumn).DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDown;
((GridViewComboBoxColumn)newColumn).AutoCompleteMode = AutoCompleteMode.SuggestAppend; 
newColumn.FieldName = "customer";
newColumn.Name = "customer";
newColumn.HeaderText = "Customer";
newColumn.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
newColumn.Width = 100;
listOfColumns.Add(newColumn);
this.MainFormGridView.Columns.Add(newColumn);

So the question is there what can I do to select specific items in the dropdownlist AND is the CellEndEdit the correct location for that (as I suspect)?

Re Captcha
  • 3,125
  • 2
  • 22
  • 34
Thomas
  • 2,886
  • 3
  • 34
  • 78

1 Answers1

0

A possible solution for the problem itself is to forego the usage of the GridViewComboboxcColumn to get a field with autocomplete and instead use a "normal" GridViewTextBoxColumn. In addition to this change we will need an customized editor which brings in the autocomplete element. One thing of note here is that the height of the cell changes slightly leading to chars being chopped off a bit if you don't have the setting active that rows can grow in size automatically (thus if that is not the case, then you need to increase the row height to at least 30: Example of how to do this in this case: MainFormGridView.TableElement.RowHeight = 30; )

The creation code for the textbox with autocomplete now changes to the following:

GridViewTextBoxColumn newColumn;
newColumn = new GridViewTextBoxColumn();
newColumn.FieldName = "customer";
newColumn.Name = "customer";
newColumn.HeaderText = "Customer";
newColumn.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter;
newColumn.Width = 100;
this.MainFormGridView.Columns.Add(newColumn);

Like I mentioned before we now need a custom editor for the autocomplete box itself:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Telerik.WinControls.UI;

namespace MyProject
{
    class customAutoCompleteBox : RadTextBoxControlEditor
    {
        protected override Telerik.WinControls.RadElement CreateEditorElement()
        {
            return new RadAutoCompleteBoxElement();
        }

        public override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
        {
            RadAutoCompleteBoxElement element = this.EditorElement as RadAutoCompleteBoxElement;
            if (element.IsAutoCompleteDropDownOpen)
            {
                return;
            }
            base.OnKeyDown(e);
        }

    }
}

Then after this is done we only need to do 2 more steps to get the new autocomplete box to function: 1.) Setting the EditorRequired and CellEditorInitialized events 2.) Writing those events

For 1.) it is quite easy to do:

    this.MainFormGridView.CellEditorInitialized += MainFormGridView_CellEditorInitialized;
    this.MainFormGridView.EditorRequired += MainFormGridView_EditorRequired;

For 2.) the code here is also quite easy to do. Although I will put in a bit of a foreword here: element.Delimiter can cause a few problems. Defaultwise one would use ' ' as delimiter there, BUT if the data itself has many blanks inside that could raise an unexpected behaviour, as each blank separated data part is seen as one "tag" or autocomplete element. Thus when the row is chosen you can get multiple tags displayed that you can delete one by one. In my case that was unwanted thus I did not use ' ' as separator but instead '\t' as the data does not have tabs inside.

Here is the code for CellEditorInitialized:

void MainFormGridView_CellEditorInitialized(object sender, GridViewCellEventArgs e)
{
            if (e.ActiveEditor is customAutoCompleteBox)
            {
                customAutoCompleteBox editor = (customAutoCompleteBox)e.ActiveEditor;
                RadAutoCompleteBoxElement element = (RadAutoCompleteBoxElement)editor.EditorElement;
                element.Delimiter = '\t';
                element.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                element.AutoCompleteDisplayMember = e.Column.Name;
                element.AutoCompleteValueMember = e.Column.Name;
                element.AutoCompleteDataSource = (from c in entity.myOffer
                                                  orderby c.customer
                                                  where c.customer!= null
                                                  select c.customer)
                                                    .Distinct()
                                                    .ToList();
            }
}

And now for ViewCellFormatting

void MainFormGridView_EditorRequired(object sender, Telerik.WinControls.UI.EditorRequiredEventArgs e)
{
        if (MainFormGridView.CurrentColumn.Name == "customer")
        {
            e.Editor = new customAutoCompleteBox();
        }
}

With this an autocomplete is possible where the original problem does not occur. The only things not so nice here are that one has to press enter 2 times (after the first time the "tags" are shown from the row that was selected, and only the 2nd enter sets the tags. Same for using TAB to move out of the cell). Additionally the combobox is only shown after typing in a char and not already from the beginning.

In total, this solution functions but the behaviour (and appearance) of the autocompletebox is slightly different from the original combobox - autocomplete box.

Edit: As it seems if you use the delimiter it adds the delimiter at the end, which can cause unwanted results (thus nothing found) if the autocomplete box is shown in an filter. A possible solution is using \0 as a delimiter so that nothing is added to the selected string from the autocomplete box. Although this also makes it so that ALL chosen elements are treeated as being one single tag.

Thomas
  • 2,886
  • 3
  • 34
  • 78