2015-08-15 95 views
1

我试图做的是使如何让我的自己的DataGridView列

  • 显示在每个单元的 下拉列表不同的项目的DataGridViewDropdownColumn。
  • DataGridViewHybridColumn 显示每个单元格的TextBox或ComboBox。

我读了this toturial并创建了我自己的DataGridViewBarColumn,但我没有丝毫的线索我应该如何实现这样的东西。

即使在DataGridView中可能有超过100K行,性能并不重要,我稍后会考虑优化。

我觉得他们就完成了同样的方式,所以我问他们一个问题

+0

我知道有http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewComboBoxCell.cs,它具有像内部重写void CacheEditingControl()这样的黑魔法。有没有人在少于4k条意大利面条线上使用可用许可证来做任何清洁工作? – Behrooz

+1

我相信这个问题可能对你有用:http://stackoverflow.com/questions/986233/windows-forms-datagridview-control-have-different-control-types-in-the-same-colu你可能有潜在的使用它作为自定义DataGridViewHybridColumn的起点,因为它应该让您按单元格而不是按列选择单元格类型。 – Calcolat

+1

@Calcolat我正在做那里已经说过的东西,目前它接近10K行代码,因为mono和.net在它们的实现中都使用了内部和内部保护方法,所以我不得不重新实现很多东西。 – Behrooz

回答

2

我可以给你一个起点上实现它:

首先,准备好你的约束力,创建你的DataGridViewComboBoxColumn。

private List<string> list = new List<string>(); 

public Form1() 
{ 
     InitializeComponent(); 

     // Data source for you dropdown list 
     list.Add("First Option"); 
     list.Add("Second Option"); 
     list.Add("Third Option"); 

     dataGridView1.AutoGenerateColumns = false; 
     dataGridView1.MultiSelect = false; 
     dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter; 
     dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; 
     dataGridView1.CellValidating += new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating); 
     dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing); 
     dataGridView1.DataError += dataGridView1_DataError; 

     // Formatting your ComboBox 
     DataGridViewComboBoxColumn comboColumn = new DataGridViewComboBoxColumn(); 
     comboColumn.FlatStyle = FlatStyle.Flat; 
     comboColumn.HeaderText = "Hybrid Data Grid Column"; 
     comboColumn.DataPropertyName = "Tag"; 
     //comboColumn.DataSource = list;   

     dataGridView1.Columns.Add(comboColumn); 
     dataGridView1.DataSource = list; 

} 

其次,附加的事件进行编辑,一旦你键入:

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
    { 
     var combo = ((DataGridView)sender).CurrentCell as DataGridViewComboBoxCell; 
     if (combo == null) 
     { 
      return; 
     } 
     if (!combo.Items.Contains(e.FormattedValue)) 
     { 
      // Add the text you type into you bound list and refresh binding 
      list.Add(e.FormattedValue.ToString()); 
      DataGridViewComboBoxColumn col = ((DataGridView)sender).CurrentCell.OwningColumn as DataGridViewComboBoxColumn; 
      col.Items.Clear(); 
      col.Items.AddRange(list); 
     } 

     // Display what you type 
     ((DataGridView)sender).CurrentCell.Value = e.FormattedValue; 
    } 

    private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
    { 
     ComboBox comboControl = e.Control as ComboBox; 
     if (comboControl != null) 
     { 
      if (comboControl.DropDownStyle != ComboBoxStyle.DropDown) 
      { 
       comboControl.DropDownStyle = ComboBoxStyle.DropDown; 
      } 
      //Update Items if list has changed (assumes items can't be deleted) 
      if (comboControl.Items.Count != list.Count) 
      { 
       DataGridViewComboBoxColumn col = ((DataGridView)sender).CurrentCell.OwningColumn as DataGridViewComboBoxColumn; 
       col.Items.Clear(); 
       col.Items.AddRange(list.ToArray()); 
       //Note: current cell's items don't appear to be refreshed by the lines above 
       comboControl.Items.Clear(); 
       comboControl.Items.AddRange(list.ToArray()); 
      } 
     } 
    } 

样本输出:

enter image description here

注:由于我们是在我们的绑定添加文本输入列出它可能会发生,一旦你点击下拉选项,你会看到额外的输入。所以,我会把它交给你来打磨它。

+0

非常感谢您为帮助我而付出的巨大努力,不幸的是,这并不是我要求的。使用这种方法,我无法为用户提供用于写入文本的“文本框”。只有一些单元格需要是组合框。这个方法的确切问题是DataGridViewEditingControlShowingEventArgs.Control是一个只读属性。我想如果我能解决这个问题或找到解决方法,问题就解决了。 – Behrooz

+1

为什么TextBox如果您可以允许在可组合框中输入文本? – jtabuloc

+0

,因为对于不同的项目有很少的组合框和100K不同的价格,用户不应该感到困惑,我可能需要稍后添加2个其他自定义用户控件以用于类似的情况。如果我可以通过像CellValueNeeded这样的事件来选择细胞类型,那真的会让我的生活更轻松。 – Behrooz