2016-12-22 10 views
2

我想DataGridView的列使用ComboBoxStyle.DropDown风格的组合框,用户可以选择在下拉列表中的一个条目,或键入任意文本。DataGridView的组合框柱,将接受任何文本

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

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

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

要清楚,列数据类型是string,我不希望它针对ComboBox的下拉列表(或其他任何事情)进行验证。

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

回答

1

我发现一个简单的,如果详细的答案。 (但我仍然想知道是否有办法用标准DataGridViewComboBoxColumn类型来做到这一点。)

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

  1. 分别DropDownComboBoxColumnDropDownComboBoxCellDropDownComboBoxEditingControl重命名三类。

  2. string替换DateTime无处不在。

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

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

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

  6. 制造DropDownComboBoxEditingControl派生自ComboBox而不是DateTimePicker

  7. 更换OnValueChangedOnTextChanged,以考虑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; 
    } 
} 

如果你想要所有行的相同的下拉项目,那么你可以总是s请将其设为DropDownComboBoxColumn的财产,如DropDownStyle,并将其设置为PrepareEditingControlForEdit以避免必须处理EditingControlShowing

0

对于您可以添加以下提到的通过后端代码数据网格视图的列:

using System.Data.SqlServerCe; 

string sqlConnection = "Data Source"; 
SqlCeConnection conn = new SqlCeConnection(sqlConnection); 
//Get bind from database. 
string qryGetCategory = "Query to get data for combo box"; 
SqlCeCommand cmdCat = new SqlCeCommand(qryGetCategory, conn); 
SqlCeDataAdapter daCat = new SqlCeDataAdapter(qryGetCategory, conn); 
DataTable dtCat = new DataTable(); 
daCat.Fill(dtCat); 

//Combobox column. 
DataGridViewComboBoxColumn ComboBoxCol = new DataGridViewComboBoxColumn(); 
ComboBoxCol.DataSource = dtCat; 
ComboBoxCol.Name = "Column name"; 
ComboBoxCol.ValueMember = "Value of member"; 
ComboBoxCol.DisplayMember = "Member to be show"; 
ComboBoxCol.DropDownStyle = ComboBoxStyle.DropDown; 
datagridview.Columns.Add(ComboBoxCol); 

请尝试它可能会解决你的问题。

+0

@Ian Goldby,如果有帮助,请将其标记为答案,以便其他人也可以从中受益,如果您有任何疑问或问题,请随时问我。 –

+0

您能否详细说明这个方法与我在问题中提供的链接中的不同之处?粘贴一段代码并不是特别有用。 –

+0

另外,'DropDownStyle'不是'DataGridViewComboBoxColumn'的属性。这是一个错字吗? –