在GridViewComboboxColumn中更改所选项目(Telerik,winforms)

时间:2014-05-05 08:30:22

标签: c# winforms autocomplete telerik datagridviewcombobox

我想知道如何设置gridviewcomboboxcolumn的所选元素。

作为一个前言:我使用具有自动完成模式的列以便 有自动完成功能,但我也想在列表中添加新元素。 到目前为止,除了一种情况外,它没有任何障碍:

我已经拥有:

T1
T12
T123

在数据源中。

然后当我选择T12并执行退格选择T1时 我有问题需要手动点击列表中的T1,因为没有选择T1,因为显示了多种可能性。因此,当我离开编辑器模式而不手动选择T1时,我将T12作为所选项目。

我希望以这样的方式更改此行为:首先找到第一个找到的项目(始终)。 (无论它是新元素还是更改为元素,所以说)

目前我已经为cellendedit添加了一个自定义处理程序,以便将新值添加到列表中:

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);
    }

}

列本身是以这种方式创建的(在被添加到gridview之前它是以下的一部分:

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);

所以我的问题是如何在下拉列表中选择特定项目并且CellEndEdit是否正确位置(我怀疑)?

1 个答案:

答案 0 :(得分:0)

问题本身的一个可能的解决方案是放弃使用GridViewComboboxcColumn来获取具有自动完成功能的字段,而是使用“普通”GridViewTextBoxColumn。 除了这个改变之外,我们还需要一个自定义编辑器来引入自动完成元素。这里需要注意的一点是,如果你没有设置激活行可以自动增大大小,那么单元格的高度会稍微改变,导致字符被略微切断(因此,如果不是这样,那么你需要将行高增加到至少30: 在这种情况下如何执行此操作的示例: MainFormGridView.TableElement.RowHeight = 30;

现在,具有自动填充功能的文本框的创建代码将更改为以下内容:

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);

就像我之前提到的,我们现在需要一个自动完成框本身的自定义编辑器:

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);
        }

    }
}

在完成此操作后,我们只需再执行2个步骤即可使新的自动完成框运行: 1.)设置EditorRequired和CellEditorInitialized事件 2.)写这些事件

对于1.)这很容易做到:

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

对于2.)这里的代码也很容易做到。虽然我会在这里提出一些前言: element.Delimiter会导致一些问题。默认情况下,会在那里使用''作为分隔符, 但是如果数据本身内部有很多空白可能引发意外行为,那么 每个空白分隔的数据部分被视为一个“标记”或自动完成元素。因此,当选择行时,您可以显示多个标签,您可以逐个删除。在我的情况下,这是不需要的,因此我没有使用''作为分隔符,而是'\ t',因为数据没有内部标签。

以下是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();
            }
}

现在适用于ViewCellFormatting

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

使用此功能可以在不发生原始问题的情况下自动完成。这里唯一不太好的是,必须按下输入2次(在第一次从所选行中显示“标签”之后,只有第二个输入设置标签。使用TAB移出相同细胞)。此外,组合框仅在输入字符后显示,而不是从一开始就显示。

总的来说,这个解决方案起作用,但自动完成框的行为(和外观)与原始组合框 - 自动完成框略有不同。

编辑: 看起来如果使用分隔符,它会在末尾添加分隔符,如果过滤器中显示自动完成框,则会导致不需要的结果(因此无法找到)。一种可能的解决方案是使用\ 0作为分隔符,以便从自动完成框中不向所选字符串添加任何内容。 虽然这也使得所有选择的元素都被树形化为一个单独的标记。