2010-01-08 21 views

Trả lời

8

Vâng, tôi đã tìm ra cách giải quyết vấn đề. Đầu tiên, tạo một lớp được gọi là CustomDataGridViewTextBoxEditingControl mà xuất phát từ DataGridViewTextBoxEditingControl, và ghi đè EditingControlWantsInputKey như thế này:

public override bool EditingControlWantsInputKey(
    Keys keyData, 
    bool dataGridViewWantsInputKey) 
{ 
    switch (keyData & Keys.KeyCode) 
    { 
     case Keys.Enter: 
      // Don't let the DataGridView handle the Enter key. 
      return true; 
     default: 
      break; 
    } 

    return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey); 
} 

này dừng DataGridView từ trao phím Enter và thay đổi các tế bào hiện tại. Tuy nhiên, nó không làm cho phím Enter thêm một dòng mới. (Có vẻ như DataGridViewTextBoxEditingControl đã xóa chức năng của phím Enter). Do đó, chúng ta cần phải ghi đè OnKeyDown và thực hiện các chức năng chính mình, như thế này:

protected override void OnKeyDown(KeyEventArgs e) 
{ 
    switch (e.KeyCode & Keys.KeyCode) 
    { 
     case Keys.Enter: 
      int oldSelectionStart = this.SelectionStart; 
      string currentText = this.Text; 

      this.Text = String.Format("{0}{1}{2}", 
       currentText.Substring(0, this.SelectionStart), 
       Environment.NewLine, 
       currentText.Substring(this.SelectionStart + this.SelectionLength)); 

      this.SelectionStart = oldSelectionStart + Environment.NewLine.Length; 
      break; 
     default: 
      break; 
    } 

    base.OnKeyDown(e); 
} 

Sau đó, tạo một lớp được gọi là CustomDataGridViewTextBoxCell mà xuất phát từ DataGridViewTextBoxCell, và ghi đè lên EditType tài sản để trả lại loại CustomDataGridViewTextBoxEditingControl.

public override Type EditType 
{ 
    get 
    { 
     return typeof(CustomDataGridViewTextBoxEditingControl); 
    } 
} 

Sau khi bạn làm điều này, bạn có thể đặt CellTemplate tài sản trên một cột hiện có để một CustomDataGridViewTextBoxCell, hoặc bạn có thể tạo ra một lớp có nguồn gốc từ DataGridViewColumn với CellTemplate cài đặt sẵn để một CustomDataGridViewTextBoxCell, và bạn sẽ có tất cả các thiết lập!

+0

Hay, tôi thích giải pháp này. Nó đã làm việc cho tôi nhưng có một điều còn thiếu. Làm thế nào tôi có thể tăng chiều cao hàng của tất cả các ô trên cùng hàng với hộp văn bản datagridview này. Điều này có thể không ?. Rõ ràng điều này cũng sẽ cần phải xảy ra khi nhấn phím. –

+0

Xin lỗi, sự cố tôi gặp phải là do thuộc tính chế độ hàng tự động của tôi được đặt cho tất cả các ô. Me.EditingControlDataGridView.Rows (EditingControlRowIndex) .Height + = 10 làm việc quyến rũ –

5

Bạn có thể thực hiện việc này bằng cách đặt thuộc tính DataGridViewCellStyle.WrapMode thành true. Từ MSDN:

Nếu WrapMode là False cho một tế bào mà chứa văn bản, các tế bào sẽ hiển thị văn bản trên một dòng duy nhất, và hiển thị bất kỳ ký tự newline nhúng như hộp ký tự. Nếu WrapMode là True cho một ô có chứa văn bản, ô hiển thị các ký tự dòng mới dưới dạng dòng ngắt, nhưng cũng bao bọc bất kỳ dòng nào vượt quá chiều rộng của ô.

Bạn có thể đặt giá trị này cho các ô cụ thể bằng cách truy cập thuộc tính Kiểu trên ô hoặc cho tất cả các ô trong cột bằng cách sử dụng DefaultCellStyle cho cột.

[Cập nhật] Để vô hiệu hóa phím Enter có chọn lọc trong DataGridView của bạn, thêm một Message Filter để Form chứa DataGridView như hình dưới đây:

private KeyMessageFilter m_filter = null; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    m_filter = new KeyMessageFilter(this); 
    Application.AddMessageFilter(m_filter); 

} 

Đây là lớp lọc thông điệp:

public class KeyMessageFilter : IMessageFilter 
{ 
    private Form m_target = null; 

    public KeyMessageFilter(Form targetForm) 
    { 
     m_target = targetForm; 
    } 

    private const int WM_KEYDOWN = 0x0100; 

    private const int WM_KEYUP = 0x0101; 


    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.Msg == WM_KEYDOWN) 
     { 
      //Note this ensures Enter is only filtered if in the 
      // DataGridViewTextBoxEditingControl and Shift is not also pressed. 
      if (m_target.ActiveControl != null && 
       m_target.ActiveControl is DataGridViewTextBoxEditingControl && 
       (Keys)m.WParam == Keys.Enter && 
       (Control.ModifierKeys & Keys.Shift) != Keys.Shift) 
      { 
       return true; 
      } 

     } 

     return false; 
    } 
} 

Bây giờ, phím Enter bị tắt khi chỉnh sửa văn bản và bạn phải bấm phím tab để di chuyển đến ô kế tiếp. Shift + Enter vẫn thêm dòng mới vào văn bản bạn đang chỉnh sửa.

Hy vọng điều này sẽ hữu ích.

+0

Cảm ơn! Câu trả lời của bạn đã khắc phục vấn đề cho phép nhiều dòng trong ô, nhưng tiếc là phím Enter vẫn thay đổi ô đã chọn. –

+0

@Zach, xem cập nhật của tôi và mã mẫu ở trên. – Ash

+0

Chỉ cần làm cho nó rõ ràng hơn, nếu WrapMode được đặt thành True thì phím enter sẽ vẫn chuyển sang hàng tiếp theo nhưng bây giờ bạn có thể sử dụng Shift + Enter để nhúng một dòng mới trong văn bản. Nếu bạn hài lòng với hành vi đó, bộ lọc thông báo là không bắt buộc. – JonP

Các vấn đề liên quan