EditingControlShowing الأحداث التي تطلق عدة مرات
-
06-09-2019 - |
سؤال
لدي DGV في VB.NET 2008 متصل بجدول Access DB. لا تتم قراءة DGV فقط، ولكن مليء بأعمدة للقراءة فقط باستثناء واحد، والذي يحتوي على مربع تحرير وسرد. يتيح مربع التحرير والسرد للمستخدم تحديد نتيجة لهذا الصف معين، ثم نسخ البرنامج في قيمة محسوبة مسبقة في عمود "الربح" اعتمادا على العنصر المحدد في COMBOBOX. ثم يضرب المستخدم الزر "حفظ" وتحديثات DB (حاليا عبر طرق SQL في XSD).
سهل بما فيه الكفاية حتى الآن.
هنا هو الرمز.
Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing
Dim combo As ComboBox = CType(e.Control, ComboBox)
If (combo IsNot Nothing) Then
// Remove an existing event-handler, if present, to avoid
// adding multiple handlers when the editing control is reused.
RemoveHandler combo.SelectedIndexChanged, _
New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)
// Add the event handler.
AddHandler combo.SelectedIndexChanged, _
New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)
End If
End Sub
Private Sub DGUBStake_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim myStatus As ComboBox = CType(sender, ComboBox)
Dim row = DGUserBets.CurrentRow
Select Case myStatus.SelectedIndex
Case 0
row.Cells("DGUBProfit").Value = 0
// pending. no action
Case 1
row.Cells("DGUBProfit").Value = row.Cells("DGUBIfWin").Value
// win
Case 2
// loses
row.Cells("DGUBProfit").Value = row.Cells("DGUBIfLose").Value
Case 3
// void
row.Cells("DGUBProfit").Value = 0
End Select
End Sub
المشكلة التي لدي هي أنه يبدو أنه يبدو أنه إذا كان المستخدم يختار النتيجة المرجوة من COMBOBOX ولكنه لا يضغط على الإدخال، فقم ببساطة بمكانة مختلفة إلى مجموعة مختلفة لتحديد النتيجة لطرد مختلف، لا يتم فصل الأحداث الأولية وبالتالي فإن الأحداث النار عدة مرات. يسبب هذا بعد ذلك أخطاء MSGBOX الافتراضية المختلفة ويجلب المشكلات عندما يحاول المستخدم ارتكاب جميع التغييرات في برنامج DB / Exit Etc وما إلى ذلك.
ما الذي أنا بحاجة لفعله؟ هل أحتاج إلى. في مكان ما من المناسب لفرض الصف لإنقاذ التغييرات؟ وأين يجب أن أسمي هذا؟
شكرا لك.
المحلول
نظرة سريعة على الرمز بإلقاء هذا السؤال: إذا قمت بإنشاء حدث جديد عند إزالة المرء الموجود هو نفسه؟
نصائح أخرى
لقد كان لدي مشكلة مماثلة، أضف معالج ل CellLeave
إذا كانت الخلية التي تم إخراجها هي الخلية التي تبحث عنها (أي e.ColumnIndex = myEditableColumn.Index
) ثم اتصل gv.endedit ()
أيضا أود أن أوصي بإجراء متغيرات أعضاء المعالجين للتخصيص والإزالة لأنه يبدو أن أجمل دائما يقول دائما إزالة جديدة وإضافة جديد.
Ckret / Quintin، شكرا لك على الردود السريعة.
يبدو أن المحاولة السريعة مع هذا الرمز أفضل وتبدو أن تنفد ويتخطأ من خلال التعليمات البرمجية لإطلاق الأحداث بشكل صحيح. أنا جديد إلى حد ما. NET كما آخر برمجة VB الحقيقية التي قمت بها كانت VB6 لذلك لست متأكدا مما إذا كانت هذه هي الطريقة الأكثر أناقة لحل المشكلة.
أيضا ملاحظة أنه عندما lasteventhandler = لا شيء، لا يرمي "إزالة الخدمات" استثناء، وهو لطيف جدا.
ربما يجب أن أقترح MS يجب تحديث هذه المقالة.
Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing
Dim combo As ComboBox = CType(e.Control, ComboBox)
Static LastEventHandler As EventHandler
If (combo IsNot Nothing) Then
// Remove an existing event-handler, if present, to avoid
// adding multiple handlers when the editing control is reused.
RemoveHandler combo.SelectedIndexChanged, _
LastEventHandler
LastEventHandler = New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)
// Add the event handler.
AddHandler combo.SelectedIndexChanged, _
LastEventHandler
End If
End Sub
رمز أبسط الذي يبدو أيضا للعمل بشكل جيد، كما اقترح Ckret:
Dim combo As ComboBox = CType(e.Control, ComboBox)
If (combo IsNot Nothing) Then
RemoveHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged
AddHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged
End If
أعلم أن هذا هو منشور قرري، ولكن بعد التصفخ مع هذه المشكلة نفسها لنصف اليوم، وجدت طريقة لحل هذه الطريقة الأخرى، لذلك اعتقدت أنه سيكون الأمر يستحق المشاركة.
إضافة معالج ثان للتعامل مع حدث إجازة من COMBOBOX الذي يزيل المعالج المنحدر الذي تم تغييره. يبدو أنه يعمل بخلايا تماما، وعلى عكس خيار آخر وجدته يمنح الإجراء المطلوب الناتج (على عكس إزالة القيمة التي تم تغييرها في حدث التعامل الفعلي الذي لن ينطلق بعد ذلك إذا قمت بالتحديد من نفس الغلغاء)
Private LastEventHandler As EventHandler = AddressOf Me.ComboBoxValueChanged
Private Sub dgvThisDatagrid_EditingControlShowing(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvOutstandingReminders.EditingControlShowing
If TypeOf (e.Control) Is ComboBox Then
Dim cboThisComboBox = DirectCast(e.Control, ComboBox)
AddHandler cboThisComboBox.SelectedValueChanged, LastEventHandler
AddHandler cboThisComboBox.Leave, AddressOf RemoveValueChangedHandler
End If
End Sub
Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As System.EventArgs)
If TypeOf (sender) Is ComboBox Then
Dim cboThisComboBox = DirectCast(sender, ComboBox)
MessageBox.Show("Value = " & cboThisComboBox.SelectedValue.ToString() & Environment.NewLine & "Text = " & cboThisComboBox.Text) ' Display index
End If
End Sub
Private Sub RemoveValueChangedHandler(ByVal sender As Object, ByVal e As System.EventArgs)
If TypeOf (sender) Is ComboBox Then
Dim cboThisCombobox = DirectCast(sender, ComboBox)
RemoveHandler cboThisCombobox.SelectedValueChanged, LastEventHandler
End If
End Sub