منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب

نسخة كاملة : تنفيذ حدث SelectedIndexChanged لأداة ListBox المرتبط برمجيا بDataTable عند فتح الفورم
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
السلام عليكم

لدي فورم قد أنشأت في بدايته متغير dt من نوع DataTable
وفي حدث الفورم أقوم بإنشاء الأعمدة للمتغير dt ثم إضافة صفوف له وبعدها اقوم بربط dt بالأداة ListBox

المشكلة أن الحدث SelectedIndexChanged الخاص بالأداة ListBox يتم اطلاقه أكثر من مره
سواء في البرنامج الأساسي أو مشروع التجربة

وللتأكد قبل وضع السؤال فقد وضعت متغير لتعداد مرات تنفيذ الحدث واظهاره في Label وبالفعل تاكدت تلك المشكلة

فكيف التغلب على عدم تنفيذ الحدث الا عندما يقوم المستخدم بالاختيار من أداة ListBox

وهذه اكواد مشروع التجربة وأساسها مقتبس من اكواد مواضيع المنتدى
ويلاحظ أنه تم تنفيذ الحدث 4 مرات عند ظهور الفورم
كود :
Public Class Form1

   Dim dt As New DataTable

   Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

       dt.Columns.Add("id", GetType(Integer))
       dt.Columns.Add("name", GetType(String))

       dt.Rows.Add(1, "Sameer")
       dt.Rows.Add(2, "Waleed")

       ListBox1.DataSource = dt
       ListBox1.ValueMember = "id"
       ListBox1.DisplayMember = "name"
       ListBox1.SelectedIndex = -1

   End Sub

   Dim i = 0
   Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
       i += 1
       Label1.Text = i
   End Sub

End Class
وشكرا لكم

نفس المشكلةتحدث مع أداة ComboBox
ولكن تم التغلب عليها باستخدام الحدث SelectionChangeCommitted بدلا من حدث SelectedIndexChanged

ولكن الأداة ListBox ليس لها حدث SelectionChangeCommitted

شكرا لكم
PHP كود :
  Dim dt As New DataTable
    Private Sub Form1_Load
(sender As System.ObjectAs System.EventArgsHandles MyBase.Load
        dt
.Columns.Add("id"GetType(Integer))
 
       dt.Columns.Add("name"GetType(String))
 
       dt.Rows.Add(1"Sameer")
 
       dt.Rows.Add(2"Waleed")
 
       ListBox1.DataSource dt
        ListBox1
.ValueMember "id"
 
       ListBox1.DisplayMember "name"
 
   End Sub
    Private Sub ListBox1_SelectedIndexChanged
(sender As System.ObjectAs System.EventArgsHandles ListBox1.SelectedIndexChanged
        Label1
.Text dt(sender.selectedindex)(1)
 
   End Sub 
يبدو اني لم استوعب المشكلة لكن لم ار مشكلة بالكود بعد التعديل
اشكرك أخي سعود على سرعة الاجابة

في البرنامج الاساسي هناك اجراءات يتم تنفيذها من داخل الحدث SelectedIndexChanged عند الاختيار
والتي لا تنبغي لها أن تحدث إلا عند اختيار المستخدم بنفسه لأحد الصفوف

أشكرك أستاذي

أداة Label ما هي الا لإظهار عدد مرات تنفيذ الحدث في مرحلة تتبع المشكلة

أشكرك أخي الكريم
اذا كنت تريد حصر الاجراء بتدخل المستخدم للبرنامج فاستخدم حدث Control_MouseClick
وتحقق من ان الزر الايسر هو الذي تم النقر عليه.

توجد بعض الظروف تجعل المبرمج يستخدم ListBox بدلا عن ComboBox
السلام عليكم اخي سمير
الكود سليم ولاتوجد اي مشكلة فيه يحمل مرة واحدة  والعدد في اللايبل هو 4
 وعند النقر على اي عنصر في الليست بوكس يتم زيادة العدد ب1 كل مرة 
اين المشكلة؟
أشكرك أستاذي الكريم سعود

الحدث MouseClick جيد،
ولكن من الشروط أن يتاح للمستخدم حرية العمل سواء الماوس أو التنقل بواسطة لوحة المفاتيح.

أثابكم الله

أشكرك أستاذي ابراهيم ايبو واعانكم

العدد 3 الذي ظهر لديك هو عدد مرات تنفيذ الحدث بدون تدخل المستخدم، وهو الذي كشف المشكلة،

يفترض بالعداد ان يكون صفرا للتأكد من أنه لم يتم تنفيذ الحدث بدون اختيار المستخدم.

وقد تم وضع هذا العداد كما اسلفت فقط من أجل تتبع المشكلة والتي اتضحت من خلال تنفيذ الحدث عند بداية الفورم.

والمفروض الحدث لا يتم اطلاقه الا عند اختيار المستخدم فقط، سواء بالماوس أو بلوحة المفاتيح.

أشكركم أساتذتي
الامر حدا عادي لان عند اضافة هذين السطرين 
 dt.Rows.Add(1, "Sameer")
        dt.Rows.Add(2, "Waleed")

يتم التغيير وهذا يحسب 1
ثم عند اضافة هذا السطر 
ListBox1.ValueMember = "id" يحسب تغيير  ثاني ويكون العد اصيح 2
وعند اضافة هذا السطر 
ListBox1.DisplayMember = "name" يحسب تغيير ثالث ويكون العد اصبح 3

فم بايقاف  هذا السطر 
ListBox1.ValueMember = "id" سيكون التغيير اصبح اثنان فقط

عملية  ListBox1_SelectedIndexChanged تحسب كل التغييرات التي طرأت على الليست بوكس
جرب اضافة هذه الاسطر 
ListBox1.SelectedIndex = 0

        ListBox1.SelectedIndex = 1
        ListBox1.SelectedIndex = 0
        ListBox1.SelectedIndex = 1
        ListBox1.SelectedIndex = 0
        ListBox1.SelectedIndex = 1
ثم انظر الى عدد مرات التغيير التي حصلت على الليست بوكس عندها ستدرك ان الامر طبيعي وان كل عملية تغيير في الليست بوكس تحسب
أشكرك أستاذي ابراهيم ايبو

فعلا اضافة الأسطر أدت لإطلاق الحدث، بارك الله فيكم

تم تعديل الكود ونجح الأمر
فقد تم نقل أسطر ربط أداة ListBox قبل أسطر الإضافة

فبقي سطر إلغاء الإختيار بوضع -1 للخاصية SelectedIndex فهي تطلق الحدث أيضا
فتم التغلب عليه بوضع شرط داخل الحدث ليتفقد قيمة SelectedIndex فإن كانت -1 يخرج من الحدث

الكود الأول بعد التعديل
كود :
Public Class Form1

   Dim dt As New DataTable

   Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

       dt.Columns.Add("id", GetType(Integer))
       dt.Columns.Add("name", GetType(String))

       ListBox1.DataSource = dt
       ListBox1.ValueMember = "id"
       ListBox1.DisplayMember = "name"

       dt.Rows.Add(1, "Sameer")
       dt.Rows.Add(2, "Waleed")

       ListBox1.SelectedIndex = -1

   End Sub

   Dim i = 0
   Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
       If ListBox1.SelectedIndex = -1 Then Exit Sub
       i += 1
       Label1.Text = i
   End Sub

End Class


أشكرك أستاذي ابراهيم ايبو على مساعدتك
أشكرك أستاذي سعود على تفاعلك مع الموضوع
الحمد لله والشكر لله

ولك اخي سمير 

كم هو رائع فهم سير الكود لانك عندها ستعرف ماتريد