بعد اذن اخي الوادي
هذه المشكلة واجهتني في يوم من الايام و و جدت الحل على الشبكة عبر اضافة كلاس خاصة تعيد تعريف القريد الافتراضي مع بعض التعديلات
ساطرحها هنا مع طريقة التعامل معها
اولا في مشروعك قم باضافة كلاس جديد و سميه APSDataGridView
بعد ذلك قم بنسخ هذا الكود و ضعه داخل الكلاس
كود :
Imports System.Windows.Forms
Namespace APS.Windows.Forms
' Derived DataGridView that takes care of the details so combo boxes use type-in (editable) mode.
Public Class APSDataGridView
Inherits System.Windows.Forms.DataGridView
' It seems to generate the delegate [event]EventHandler automatically from the event declaration...
'Public Delegate Sub ComboBoxItemNotInListEventHandler(ByVal dgv As DataGridView, ByVal cbo As ComboBox, ByVal cboColumn As DataGridViewComboBoxColumn, ByVal e As DataGridViewCellValidatingEventArgs)
Public Event ComboBoxItemNotInList(ByVal dgv As DataGridView, ByVal cbo As ComboBox, ByVal cboColumn As DataGridViewComboBoxColumn, ByVal e As DataGridViewCellValidatingEventArgs)
' Constructor
Public Sub New()
MyBase.New()
End Sub
' This makes combo boxes "editable" so you can type in them. See the DataGridView FAQ.
Protected Overrides Sub OnEditingControlShowing(
ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs)
Dim dgv As DataGridView = Me 'sender
If (TypeOf e.Control Is ComboBox) Then
Dim cbo As ComboBox = DirectCast(e.Control, ComboBox)
' Optional: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=254131&SiteID=1
'cbo.AutoCompleteMode = AutoCompleteMode.SuggestAppend
'cbo.AutoCompleteSource = AutoCompleteSource.ListItems
' This makes it a type-in combo box
cbo.DropDownStyle = ComboBoxStyle.DropDown
' Adjust the ComboBox behavior:
AddHandler cbo.PreviewKeyDown, New PreviewKeyDownEventHandler(AddressOf comboBox_PreviewKeyDown)
' (Thanks to Ying Liu, Microsoft SupportSmile
dgv.NotifyCurrentCellDirty(True)
End If
' Call registered event handlers...
MyBase.OnEditingControlShowing(e)
End Sub
' Validate typed-in values...
Protected Overrides Sub OnCellValidating(ByVal e As DataGridViewCellValidatingEventArgs)
Dim dgv As DataGridView = Me 'sender
If Not TypeOf (dgv.EditingControl) Is ComboBox Then
' Every control path should call MyBase.OnCellValidating
MyBase.OnCellValidating(e)
Else
Dim cbo As ComboBox = dgv.EditingControl
If (cbo Is Nothing) Then
MyBase.OnCellValidating(e)
Exit Sub ' cbo is Nothing if the user did not edit the cell
End If
' This does two things:
' (1) This makes the combo box case-insensitive.
' (2) You have to force the SelectedIndex when using type-in mode or it will not properly recognize the change
' This little gem comes from
' http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=254131&SiteID=1
cbo.SelectedIndex = cbo.FindStringExact(cbo.Text.Trim)
' You could customize the handling below on a column-by-column basis...
If cbo.SelectedIndex = -1 Then ' The item wasn't in the list...
' Is it because the value is empty?
If (cbo.Text.Trim = String.Empty) Then
' We assume that it's okay to have an empty value here...
' Let the user delete the value...
' Don't Raise Event ComboBoxItemNotInList...
Else
' A value was entered but it was not in the list...
Dim cboColumn As DataGridViewComboBoxColumn = dgv.Columns(e.ColumnIndex)
RaiseEvent ComboBoxItemNotInList(dgv, cbo, cboColumn, e)
If (e.Cancel = True) Then
' How do we cancel a value if it creates a new row?
Beep() ' Set a breakpoint here
' ? force dgv value to empty???
' Don't return yet - we still need to call the base class event handler
Else
' If the user added the item to the combo box, we need to accept the new value...
' Again, from http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=254131&SiteID=1
cbo.SelectedIndex = cbo.FindStringExact(cbo.Text.Trim)
End If
End If
End If
End If
' Call the base class handler and user handlers...
MyBase.OnCellValidating(e)
End Sub
Protected Shared Sub comboBox_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs)
' There is a glitch if you are using a ComboBox either in a DataGridView or standalone.
' If you open the ComboBox dropdown but then type a value and press ENTER, the value is lost.
' This error does not appear if you press TAB.
' This is the workaround.
If (e.KeyCode = Keys.Enter) Then
Dim cbo As ComboBox = sender
If cbo.DroppedDown Then
cbo.DroppedDown = False
End If
End If
' Allow the ESC key to cancel changes even if AutoComplete mode has been active.
If (e.KeyCode = Keys.Escape) Then
Dim cbo As ComboBox = sender
' I don't know why this works, but it does:
cbo.Text = ""
End If
End Sub
End Class
End Namespace
الان قم بحفظ المشروع ثم قم بعملية Build للمشروع و ستظهر لديك قريد جديدة في صندوق الادوات باسم APSDataGridView
قم باضافتها الى المشروع و تعامل معها بالشكل الافتراضي
الان في Form1
عرف مايلي
كود :
Enum CBO_MODE
NORMAL = 0
EDITABLE = 1
EDITABLE_WITH_NOTIFYCURRENTCELLDIRTY = 2
End Enum
Const ALLOW_ADDS As Boolean = True
Private MODE As CBO_MODE = CBO_MODE.EDITABLE_WITH_NOTIFYCURRENTCELLDIRTY
الان كل ما تحتاج اليه هو معالجة الحدثين التاليين كما يلي
كود :
Private Sub ApsDataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles ApsDataGridView1.EditingControlShowing
' هنا تستطيع التحكم اذا كان العنصر قابل للتعديل اما لا
If e.CellStyle.Tag = "editable" Then
Dim dataGridView1 As DataGridView = CType(sender, DataGridView)
If (TypeOf (e.Control) Is ComboBox) Then
Dim cb As ComboBox = CType(e.Control, ComboBox)
If (Not cb Is Nothing) Then
cb.DropDownStyle = ComboBoxStyle.DropDown
If (MODE = CBO_MODE.EDITABLE_WITH_NOTIFYCURRENTCELLDIRTY) Then
dataGridView1.NotifyCurrentCellDirty(True)
End If
End If
End If
End If
End Sub
كود :
Private Sub ApsDataGridView1_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles ApsDataGridView1.CellValidating
Dim dataGridView1 As DataGridView = CType(sender, DataGridView)
If (TypeOf dataGridView1.Columns(e.ColumnIndex) Is DataGridViewComboBoxColumn) Then
Dim comboBoxColumn As DataGridViewComboBoxColumn = dataGridView1.Columns(e.ColumnIndex)
If (Not comboBoxColumn.Items.Contains(e.FormattedValue)) Then
If (ALLOW_ADDS) Then
Beep() ' تم اضافة صوت يمكنك الغائه
comboBoxColumn.Items.Add(e.FormattedValue)
Else
' هنا للاغلاق
e.Cancel = True
End If
End If
End If
End Sub