Bugün sizlere, C# .NET Framework 4 ve Microsoft Visual Studio 2010 kullanarak, nasıl düzenlenebilir bir ListView oluşturacağınızı anlatacağım. ListView kontrolü, verileri satır ve sütunlar halinde görüntülemek için sıkça kullanılır. Bu makalede, bu kontrolü kullanarak kullanıcıların doğrudan hücreler üzerinde değişiklik yapabileceği bir yapı oluşturacağız.
Düzenlenebilir ListView Nedir?
Düzenlenebilir bir ListView, kullanıcıların içindeki verilere doğrudan müdahale edebildiği bir kontrol anlamına gelir. Kullanıcılar bir hücreye tıkladığında, o hücre bir metin kutusu veya açılır liste gibi bir düzenleme kontrolüne dönüşür ve kullanıcı veriyi değiştirebilir.
C# ile Düzenlenebilir ListView Oluşturma
Aşağıdaki adımları izleyerek, düzenlenebilir bir ListView oluşturabilirsiniz:
- Yeni Bir Sınıf Oluşturun: ListViewEx adında, ListView sınıfından türeyen
yeni bir sınıf oluşturun. Bu sınıf, düzenleme işlevselliğini ekleyeceğimiz
yer olacak.
using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace Webkolog { public class ListViewEx : ListView { // Gerekli Win32 API tanımları ve değişkenler buraya gelecek } }
- Win32 API Fonksiyonlarını Tanımlayın: LVM_GETSUBITEMRECT mesajını göndermek için
user32.dll içindeki SendMessage fonksiyonunu kullanmamız gerekiyor. Bu
mesaj, bir alt öğenin (subitem) dikdörtgen alanını almak için kullanılır.
Ayrıca, hücrenin konumunu ve boyutunu elde etmek için bir RECT yapısı
tanımlayacağız.
[StructLayout(LayoutKind.Sequential)] internal struct RECT { public int left; public int top; public int right; public int bottom; } internal class Win32 { public const int LVM_GETSUBITEMRECT = (0x1000) + 56; public const int LVIR_BOUNDS = 0; [DllImport("user32.dll", SetLastError = true)] public static extern int SendMessage(IntPtr hWnd, int messageID, int wParam, ref RECT lParam); }
- Gerekli Değişkenleri ve Kontrolleri Ekleyin: Düzenleme sırasında kullanılacak TextBox ve
ComboBox kontrollerini, ayrıca hücre bilgilerini ve diğer yardımcı
değişkenleri sınıfımıza ekleyelim.
private TextBox textBox = new TextBox(); private ComboBox combo = new ComboBox(); private int editingRow = -1; private int editingCol = -1; private bool mouseDown = false; private Hashtable customCells = new Hashtable(); private bool addSubItem = false; public bool AddSubItem { set { this.addSubItem = value; } } private bool hideComboAfterSelChange = false; public bool HideComboAfterSelChange { set { this.hideComboAfterSelChange = value; } }
- Kurucu Metodu ve InitializeComponent Metodunu
Oluşturun: Bu metotlar
içinde, metin kutusu ve açılır liste kontrollerini oluşturup, gerekli
olayları atayacağız.
public ListViewEx() { InitializeComponent(); } private void InitializeComponent() { textBox.Visible = false; textBox.BorderStyle = BorderStyle.FixedSingle; textBox.Leave += new EventHandler(textBox_Leave); combo.Visible = false; Controls.Add(textBox); Controls.Add(combo); combo.DropDownStyle = ComboBoxStyle.DropDownList; combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged); }
- GetSubItemRect Metodunu Oluşturun: Bu metot, tıklanan hücrenin konumunu ve boyutunu
almak için LVM_GETSUBITEMRECT mesajını gönderir.
private RECT GetSubItemRect(Point clickPoint) { RECT subItemRect = new RECT(); editingRow = editingCol = -1; ListViewItem item = GetItemAt(clickPoint.X, clickPoint.Y); if (item != null) { for (int index = 0; index < Columns.Count; index++) { subItemRect.top = index + 1; subItemRect.left = Win32.LVIR_BOUNDS; int result = Win32.SendMessage(Handle, Win32.LVM_GETSUBITEMRECT, item.Index, ref subItemRect); if (result != 0) { if (clickPoint.X < subItemRect.left) { editingRow = item.Index; editingCol = 0; break; } if (clickPoint.X >= subItemRect.left && clickPoint.X <= subItemRect.right) { editingRow = item.Index; editingCol = index + 1; break; } } } } return subItemRect; }
- AddEditableCell ve AddComboBoxCell Metotlarını
Oluşturun: Bu
metotlar, hangi hücrelerin düzenlenebilir olacağını veya hangi hücrelerde
açılır liste gösterileceğini belirtmek için kullanılır.
1. public void AddEditableCell(int row, int col) { customCells[new SubItem(row, col)] = null; } public void AddComboBoxCell(int row, int col, StringCollection data) { customCells[new SubItem(row, col)] = data; } public void AddComboBoxCell(int row, int col, string[] data) { StringCollection param = new StringCollection(); param.AddRange(data); AddComboBoxCell(row, col, param); } internal class SubItem { public readonly int row; public readonly int col; public SubItem(int row, int col) { this.row = row; this.col = col; } }
- ShowTextBox ve ShowComboBox Metotlarını
Oluşturun: Bu
metotlar, düzenleme kontrolünü (metin kutusu veya açılır liste) hücrenin
üzerinde görüntüler.
1. private void ShowTextBox(Point location, Size size) { textBox.Size = size; textBox.Location = location; textBox.Text = Items[editingRow].SubItems[editingCol].Text; textBox.Show(); textBox.Focus(); } private void ShowComboBox(Point location, Size size, StringCollection data) { combo.Size = size; combo.Location = location; combo.Items.Clear(); foreach (string text in data) { combo.Items.Add(text); } combo.Text = Items[editingRow].SubItems[editingCol].Text; combo.DropDownWidth = GetDropDownWidth(data); combo.Show(); } private int GetDropDownWidth(StringCollection data) { if (data.Count == 0) { return combo.Width; } string maximum = data[0]; foreach (string text in data) { if (maximum.Length < text.Length) { maximum = text; } } return (int)(CreateGraphics().MeasureString(maximum, Font).Width); }
- OnMouseUp Metodunu Override Edin: Bu metot, kullanıcı hücreye tıkladığında
tetiklenir. Burada, tıklanan hücrenin düzenlenebilir olup olmadığını
kontrol edip, uygun düzenleme kontrolünü görüntüleriz.
1. protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); try { textBox.Visible = combo.Visible = false; if (!mouseDown) { return; } if (!FullRowSelect || View != View.Details) { return; } mouseDown = false; RECT rect = GetSubItemRect(new Point(e.X, e.Y)); if (editingRow != -1 && editingCol != -1) { SubItem cell = GetKey(new SubItem(editingRow, editingCol)); if (cell != null) { Size size = new Size(Columns[editingCol].Width, Items[editingRow].Bounds.Height); Point location = editingCol == 0 ? new Point(0, rect.top) : new Point(rect.left, rect.top); ValidateAndAddSubItems(); if (customCells[cell] == null) { ShowTextBox(location, size); } else { ShowComboBox(location, size, (StringCollection)customCells[cell]); } } } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } } private void ValidateAndAddSubItems() { try { while (Items[editingRow].SubItems.Count < Columns.Count && addSubItem) { Items[editingRow].SubItems.Add(""); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } } private SubItem GetKey(SubItem cell) { try { foreach (SubItem key in customCells.Keys) { if (key.row == cell.row && key.col == cell.col) { return key; } else if (key.row == -1 && key.col == cell.col) { return key; } else if (key.row == cell.row && key.col == -1) { return key; } else if (key.row == -1 && key.col == -1) { return key; } } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } return null; }
- OnMouseDown Metodunu Override Edin: Bu metot, kullanıcı ListView içinde bir yere
tıkladığında tetiklenir. Burada, düzenleme kontrollerini gizleyeceğiz.
1. protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); try { mouseDown = true; textBox.Hide(); combo.Hide(); } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } }
- textBox_Leave ve combo_SelectedIndexChanged
Olaylarını Oluşturun: Bu olaylar,
kullanıcı metin kutusundan ayrıldığında veya açılır listeden bir seçim
yaptığında tetiklenir. Burada, yeni değeri hücreye kaydedeceğiz.
1. private void textBox_Leave(object sender, EventArgs e) { try { if (editingRow != -1 && editingCol != -1) { Items[editingRow].SubItems[editingCol].Text = textBox.Text; textBox.Hide(); } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } } private void combo_SelectedIndexChanged(object sender, EventArgs e) { try { if (editingRow != -1 && editingCol != -1) { Items[editingRow].SubItems[editingCol].Text = combo.Text; combo.Visible = !hideComboAfterSelChange; } } catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.ToString()); } }
Nasıl Kullanılır?
- ListViewEx sınıfının bir örneğini oluşturun.
- View özelliğini View.Details olarak ayarlayın ve sütunlar ekleyin.
- AddEditableCell veya AddComboBoxCell metotlarını kullanarak, hangi hücrelerin düzenlenebilir olacağını belirtin.
- ListView'e öğeler ekleyin.
1. ListViewEx listViewEx = new ListViewEx(); listViewEx.View = View.Details; listViewEx.Columns.Add("Ad", 100); listViewEx.Columns.Add("Soyad", 100); listViewEx.Columns.Add("Not", 100); listViewEx.AddEditableCell(-1, 0); // Tüm satırlardaki ilk sütun düzenlenebilir listViewEx.AddEditableCell(-1, 1); StringCollection grades = new StringCollection(); grades.AddRange(new string[] { "A", "B", "C", "D", "E" }); listViewEx.AddComboBoxCell(-1, 2, grades); listViewEx.Items.Add(new ListViewItem(new string[] { "Ahmet", "Yılmaz", "A" })); listViewEx.Items.Add(new ListViewItem(new string[] { "Ayşe", "Demir", "B" }));
Bu adımları tamamladıktan sonra, kullanıcıların ListView içindeki hücrelere tıklayarak verileri düzenleyebildiğini göreceksiniz. Bu, özellikle kullanıcıların uygulama içinde veri girişi yapması gereken durumlarda oldukça kullanışlıdır.
Webkolog'u takipte kalın!
Hepinize bol kodlu ve başarılı projeler dilerim!
0 yorum:
Yorum Gönder