2009-11-29 114 views
27

我需要以編程方式在編輯模式下設置單元格。我知道將該單元格設置爲CurrentCell,然後調用BeginEdit(bool)方法,它應該發生,但在我的情況下,它不會。Datagridview:如何在編輯模式下設置單元格?

我真的很想,用我的幾列DGV,用戶只能選擇並編輯前兩個。其他列已經是隻讀的,但用戶可以選擇它們,這就是我不想要的。

所以我在想,告訴用戶TAB每次它已經寫完的單元格,然後選擇第二個單元格,然後重新標籤,並選擇它,並開始編輯下一行的第一個單元格...

我怎樣才能做到這一點?

回答

61

設置CurrentCell,然後調用BeginEdit(true)對我很好。

以下代碼顯示將單元設置爲可編輯的KeyDown事件的eventHandler。

我的例子只實現了所需的按鍵覆蓋之一,但理論上其他人應該工作相同。 (我總是設置[0] [0]電池爲可編輯,但任何其他電池即可工作)

private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Tab && dataGridView1.CurrentCell.ColumnIndex == 1) 
     { 
      e.Handled = true; 
      DataGridViewCell cell = dataGridView1.Rows[0].Cells[0]; 
      dataGridView1.CurrentCell = cell; 
      dataGridView1.BeginEdit(true);    
     } 
    } 

如果你還沒有找到它之前,該DataGridView FAQ是一個很好的資源,以書面形式DataGridView控件的程序管理器,涵蓋了大部分您可能想要對控件執行的操作。

+0

謝謝... 首先,我嘗試使用SelectionChange事件,並做一些艱苦(及uggly太)工作,以避免堆棧溢出,因爲everytimes選擇改變它再次閃光。 但現在,我喜歡的FAQ最你的解決方案......並感謝+1。我更習慣於web而不是winforms,但無論如何都很好。 謝謝! – josecortesp 2009-11-29 03:59:13

+1

這正是我所需要的。 Sort ... :)我實際上是試圖更新綁定到數據源的網格外部的單元格內容。我可以在屏幕上放置新值,但保存按鈕保存舊值。我需要在更新值之前放置一個CurrentCell和EndEdit()。你的回答讓我完全走上正軌。謝謝! – BoltBait 2009-12-08 20:21:25

+0

避免需要問一個類似的問題 - ty – IbrarMumtaz 2012-11-17 15:58:06

2

那麼,我會檢查你的任何列是否設置爲ReadOnly。我從來沒有使用BeginEdit,但也許有一些合法的使用。一旦完成dataGridView1.Columns[".."].ReadOnly = False;,不是ReadOnly的字段應該是可編輯的。您可以使用DataGridView CellEnter事件來確定哪些單元格輸入了,然後在您從前兩列向下一列列進行編輯後關閉對這些單元格的編輯,並關閉最後兩列的編輯。

5
private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e) 
{ 
    if (DgvRoomInformation.CurrentCell.ColumnIndex == 4) //example-'Column index=4' 
    { 
    DgvRoomInformation.BeginEdit(true); 
    } 
} 
1

我知道這個問題很老了,但是我想分享一些演示代碼這個問題幫助了我。

  • 創建一個具有ButtonDataGridView
  • 表格註冊一個Click事件爲Button1
  • 爲DataGridView1
  • 集DataGridView1的財產EditMode註冊一個CellClick事件EditProgrammatically
  • 下面的代碼粘貼到Form1:
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     DataTable m_dataTable; 
     DataTable table { get { return m_dataTable; } set { m_dataTable = value; } } 

     private const string m_nameCol = "Name"; 
     private const string m_choiceCol = "Choice"; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     class Options 
     { 
      public int m_Index { get; set; } 
      public string m_Text { get; set; } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      table = new DataTable(); 
      table.Columns.Add(m_nameCol); 
      table.Rows.Add(new object[] { "Foo" }); 
      table.Rows.Add(new object[] { "Bob" }); 
      table.Rows.Add(new object[] { "Timn" }); 
      table.Rows.Add(new object[] { "Fred" }); 

      dataGridView1.DataSource = table; 

      if (!dataGridView1.Columns.Contains(m_choiceCol)) 
      { 
       DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn(); 
       txtCol.Name = m_choiceCol; 
       dataGridView1.Columns.Add(txtCol); 
      } 

      List<Options> oList = new List<Options>(); 
      oList.Add(new Options() { m_Index = 0, m_Text = "None" }); 
      for (int i = 1; i < 10; i++) 
      { 
       oList.Add(new Options() { m_Index = i, m_Text = "Op" + i }); 
      } 

      for (int i = 0; i < dataGridView1.Rows.Count - 1; i += 2) 
      { 
       DataGridViewComboBoxCell c = new DataGridViewComboBoxCell(); 

       //Setup A 
       c.DataSource = oList; 
       c.Value = oList[0].m_Text; 
       c.ValueMember = "m_Text"; 
       c.DisplayMember = "m_Text"; 
       c.ValueType = typeof(string); 

       ////Setup B 
       //c.DataSource = oList; 
       //c.Value = 0; 
       //c.ValueMember = "m_Index"; 
       //c.DisplayMember = "m_Text"; 
       //c.ValueType = typeof(int); 

       //Result is the same A or B 
       dataGridView1[m_choiceCol, i] = c; 
      } 
     } 

     private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) 
     { 
      if (e.ColumnIndex >= 0 && e.RowIndex >= 0) 
      { 
       if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns.IndexOf(dataGridView1.Columns[m_choiceCol])) 
       { 
        DataGridViewCell cell = dataGridView1[m_choiceCol, e.RowIndex]; 
        dataGridView1.CurrentCell = cell; 
        dataGridView1.BeginEdit(true); 
       } 
      } 
     } 
    } 
} 

請注意,列索引號可以從按鈕按鈕的多個按鈕更改,所以我總是通過名稱而不是索引值引用列。我需要將David Hall的答案加入到我已經有ComboBoxes的演示中,以便他的答案非常有效。

0

我知道這是一個老問題,但沒有答案的工作對我來說,因爲我想可靠(總能)設置單元格進入編輯模式可能執行其他的事件,如工具欄按鈕點擊,菜單選擇時等等,這些事件可能會影響這些事件返回後的默認焦點。我最終需要一個計時器並調用。以下代碼位於從DataGridView派生的新組件中。此代碼可以讓我簡單地做出myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName);隨時調用我想任意設置一個數據綁定細胞到編輯模式(假設該小區不是隻讀模式)。

// If the DGV does not have Focus prior to a toolbar button Click, 
// then the toolbar button will have focus after its Click event handler returns. 
// To reliably set focus to the DGV, we need to time it to happen After event handler procedure returns. 

private string m_SelectCellFocus_DataPropertyName = ""; 
private System.Timers.Timer timer_CellFocus = null; 

public void CurrentRow_SelectCellFocus(string sDataPropertyName) 
{ 
    // This procedure is called by a Toolbar Button's Click Event to select and set focus to a Cell in the DGV's Current Row. 
    m_SelectCellFocus_DataPropertyName = sDataPropertyName; 
    timer_CellFocus = new System.Timers.Timer(10); 
    timer_CellFocus.Elapsed += TimerElapsed_CurrentRowSelectCellFocus; 
    timer_CellFocus.Start(); 
} 


void TimerElapsed_CurrentRowSelectCellFocus(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    timer_CellFocus.Stop(); 
    timer_CellFocus.Elapsed -= TimerElapsed_CurrentRowSelectCellFocus; 
    timer_CellFocus.Dispose(); 
    // We have to Invoke the method to avoid raising a threading error 
    this.Invoke((MethodInvoker)delegate 
    { 
    Select_Cell(m_SelectCellFocus_DataPropertyName); 
    }); 
} 


private void Select_Cell(string sDataPropertyName) 
{ 
    /// When the Edit Mode is Enabled, set the initial cell to the Description 
    foreach (DataGridViewCell dgvc in this.SelectedCells) 
    { 
    // Clear previously selected cells 
    dgvc.Selected = false; 
    } 
    foreach (DataGridViewCell dgvc in this.CurrentRow.Cells) 
    { 
    // Select the Cell by its DataPropertyName 
    if (dgvc.OwningColumn.DataPropertyName == sDataPropertyName) 
    { 
     this.CurrentCell = dgvc; 
     dgvc.Selected = true; 
     this.Focus(); 
     return; 
    } 
    } 
} 
相關問題