c# - 将接受任何文本的 DataGridView ComboBox 列

标签 c# winforms datagridview combobox

我想要一个 DataGridView 的列使用 ComboBoxStyle.DropDown样式 ComboBox,用户可以在其中选择下拉列表中的条目之一,或键入任意文本。

目前,我正在使用 this answer 中的代码我可以在 ComboBox 的文本框部分自由输入,但如果我输入的内容不在下拉列表中,则它不会提交回数据源,并且该字段将恢复为原始选择。此外,如果我以编程方式将文本设置为不在下拉列表中的内容,我会得到 DataError。事件“DataGridViewComboBoxCell 值无效。”

我正在使用数据绑定(bind); DataGridView本身绑定(bind)到 BindingList<T> .

不同于this question我不想将自由文本添加到下拉列表中。

明确一点,列的数据类型是string而且我不希望它根据 ComboBox 的下拉列表(或与此相关的任何其他内容)进行验证。

(我是否必须按照 How to: Host Controls in Windows Forms DataGridView Cells 中的描述创建自己的自定义 DataGridViewColumn 后代?)

最佳答案

我找到了一个简单但冗长的答案。 (但我仍然想知道是否有办法用标准的 DataGridViewComboBoxColumn 类型来做到这一点。)

我按照How to: Host Controls in Windows Forms DataGridView Cells中的方法做了.我的完整解决方案太长,无法在此处发布,但我可以总结一下所做的更改,使其使用 ComboBox 而不是示例的 DateTimePicker 控件。

  1. 分别重命名三个类 DropDownComboBoxColumnDropDownComboBoxCellDropDownComboBoxEditingControl

  2. string 替换所有地方的 DateTime

  3. 添加属性 public ComboBoxStyle DropDownStyle { get;放; DropDownComboBoxColumn 以允许调用代码设置下拉样式。

  4. DropDownComboBoxCell 构造函数中删除代码。

  5. DropDownComboBoxEditingControl 构造函数中删除代码。

  6. 使 DropDownComboBoxEditingControl 派生自 ComboBox 而不是 DateTimePicker

  7. OnValueChanged 替换为 OnTextChanged 以说明 ComboBoxDateTimePicker 中的不同命名。

  8. 使 EditingControlFormattedValue 属性获取和设置继承的 Text 属性(而不是 Value)并且不需要解析。

  9. 使 ApplyCellStyleToEditingControl 设置 ForeColorBackColor 而不是 CalendarForeColorCalendarMonthBackground.

  10. 使 EditingControlWantsInputKey 也声明 F4,以便它可用于打开和关闭下拉菜单。

  11. 将以下代码添加到PrepareEditingControlForEdit:

    DropDownComboBoxColumn col = _dataGridView.Columns[_dataGridView.CurrentCell.ColumnIndex] as DropDownComboBoxColumn;
    if (col == null)
    {
      throw new InvalidCastException("Must be in a DropDownComboBoxColumn");
    }
    DropDownStyle = col.DropDownStyle;
    // (If you don't explicitly set the Text then the current value is
    // always replaced with one from the drop-down list when edit begins.)
    Text = _dataGridView.CurrentCell.Value as string;
    SelectAll();
    

处理 DataGridViewEditingControlShowing 事件,如 OhBeWise's回答相关问题以设置下拉项,如果需要,还可以设置自动完成模式:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
  ComboBox box = e.Control as ComboBox;
  if (box != null)
  {
    box.AutoCompleteSource = AutoCompleteSource.ListItems;
    box.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
    box.DataSource = _dropDownItems;
  }
}

如果您希望所有行都使用相同的下拉项,那么您始终可以将其设为 DropDownComboBoxColumn 的属性,例如 DropDownStyle 并在 PrepareEditingControlForEdit 中进行设置 以避免必须处理 EditingControlShowing

关于c# - 将接受任何文本的 DataGridView ComboBox 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41281920/

相关文章:

c# - 使用 HtmlAgilityPack .NET 解析出 iframe 中的隐藏字段

c# - IL代码中maxstack值的计算

.net - 将字体动态设置为 DatagridView 的单元格

c# - .net 中 Sha256 的更新功能在哪里?

c# - 如何使用 C# 删除 Xml 中的空值子节点

c# - 如何解决 "The operation has timed out"错误

winforms - 在 Windows 窗体中仅显示具有透明度的图像?

c# - 奇怪的 BeginInvoke 行为 C#

c# - 自定义自动生成类的显示

sql-server - 如何将图像插入到 SQL Server 数据库表中