it-swarm.asia

كيفية التعامل مع الحدث انقر في "زر العمود" في Datagridview؟

أقوم بتطوير تطبيق Windows باستخدام C #. أنا أستخدم DataGridView لعرض البيانات. لقد أضفت عمود زر في ذلك. أريد أن أعرف كيف يمكنني التعامل مع الحدث انقر على هذا الزر في DataGridView.

119
Himadri

لقد أضفت زرًا إلى DataGridView وتريد تشغيل بعض الأكواد عند النقر فوقه.
سهل سهل - فقط اتبع الخطوات التالية:

يترك:

أولاً ، إليك مالاللقيام به:

أود أن أتجنب الاقتراحات الواردة في بعض الإجابات الأخرى هنا وحتى المقدمة من الوثائق في MSDN لفك تشفير فهرس العمود أو اسم العمود من أجل تحديد ما إذا كان قد تم النقر فوق زر. يسجل حدث النقرة على الشبكة بالكامل ، لذا فأنت تحتاج بطريقة ما إلى تحديد أن زرًا قد نقر ، لكن يجب ألا تفعل ذلك بافتراض أن الزر الخاص بك يعيش في اسم عمود معين أو فهرس ... هناك طريقة أسهل ...

أيضا ، كن حذرا في هذا الحدث الذي تريد التعامل معه. مرة أخرى ، فإن الوثائق والعديد من الأمثلة تخطئ. تتعامل معظم الأمثلة مع CellClick الحدث الذي سيتم إطلاقه:

عند النقر فوق أي جزء من الخلية.

... ولكن سيتم إطلاقه أيضًا عند النقر فوق رأس صف. يستلزم ذلك إضافة رمز إضافي لمجرد تحديد ما إذا كانت قيمة e.RowIndex أقل من 0

بدلاً من ذلك ، قم بمعالجة CellContentClick الذي يحدث فقط:

عند النقر فوق المحتوى الموجود داخل الخلية

لأي سبب من الأسباب ، يعتبر رأس العمود أيضًا "محتوى" داخل الخلية ، لذلك لا يزال يتعين علينا التحقق من ذلك أدناه.

دوس:

إذن إليك ما يجب عليك فعله:

أولاً ، {cast المرسل لكتابة DataGridView لكشف خصائصه الداخلية في وقت التصميم. يمكنك تعديل الكتابة على المعلمة ، لكن هذا قد يجعل أحيانًا إضافة أو إزالة معالجات صعبة.

بعد ذلك ، لمعرفة ما إذا كان قد تم النقر على زر ، ما عليك سوى التحقق للتأكد من أن العمود الذي يرفع الحدث من النوع DataGridViewButtonColumn . نظرًا لأننا أرسلنا بالفعل المرسل إلى كتابة DataGridView ، يمكننا الحصول على مجموعة Columns وتحديد العمود الحالي باستخدام e.ColumnIndex. ثم تحقق مما إذا كان هذا الكائن من النوع DataGridViewButtonColumn.

بالطبع ، إذا كنت بحاجة إلى التمييز بين أزرار متعددة لكل شبكة ، فيمكنك حينئذٍ الاختيار بناءً على اسم العمود أو الفهرس ، ولكن لا ينبغي أن يكون هذا الاختيار الأول. تأكد دائمًا من النقر فوق الزر أولاً ثم التعامل مع أي شيء آخر بشكل مناسب. في معظم الحالات حيث يكون لديك زر واحد فقط لكل شبكة ، يمكنك القفز مباشرة إلى السباقات.

ضع كل شيء معا:

C # :

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    var senderGrid = (DataGridView)sender;

    if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
        e.RowIndex >= 0)
    {
        //TODO - Button Clicked - Execute Code Here
    }
}

VB:

Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) _
                                           Handles DataGridView1.CellContentClick
    Dim senderGrid = DirectCast(sender, DataGridView)

    If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso
       e.RowIndex >= 0 Then
        'TODO - Button Clicked - Execute Code Here
    End If

End Sub

التحديث 1 - حدث مخصص

إذا كنت ترغب في الحصول على القليل من المرح ، يمكنك إضافة الحدث الخاص بك ليتم رفعه عند النقر فوق زر على DataGrid. لا يمكنك إضافته إلى DataGrid نفسه ، دون الفوضى مع الميراث وما إلى ذلك ، ولكن يمكنك إضافة حدث مخصص إلى النموذج الخاص بك وإطلاقه عند الاقتضاء. إنه رمز أكثر قليلاً ، ولكن الجانب العلوي هو أنك فصلت ما تريد القيام به عند النقر فوق زر مع كيفية تحديد ما إذا كان قد تم النقر فوق زر.

فقط قم بالإعلان عن الحدث ، وارفعه عند الاقتضاء ، وقم بالتعامل معه. سيبدو مثل هذا:

Event DataGridView1ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)

Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
    Dim senderGrid = DirectCast(sender, DataGridView)
    If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
        RaiseEvent DataGridView1ButtonClick(senderGrid, e)
    End If
End Sub

Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) Handles Me.DataGridView1ButtonClick
    'TODO - Button Clicked - Execute Code Here
End Sub

تحديث 2 - الشبكة الموسعة

ما سيكون شيئًا رائعًا هو أننا كنا نعمل مع شبكة قامت بهذه الأشياء من أجلك. يمكننا الإجابة على السؤال الأولي بسهولة: you've added a button to your DataGridView and you want to run some code when it's clicked. إليك مقاربة تمد DataGridView. قد لا يكون الأمر يستحق المتاعب المتمثلة في الاضطرار إلى تسليم عنصر تحكم مخصص مع كل مكتبة ، ولكنه على الأقل يعيد استخدام الرمز المستخدم لتحديد ما إذا تم النقر على زر.

فقط أضف هذا إلى مجموعتك:

Public Class DataGridViewExt : Inherits DataGridView

    Event CellButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)

    Private Sub CellContentClicked(sender As System.Object, e As DataGridViewCellEventArgs) Handles Me.CellContentClick
        If TypeOf Me.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
            RaiseEvent CellButtonClick(Me, e)
        End If
    End Sub

End Class

هذا هو. لا تلمسها مرة أخرى. تأكد من أن DataGrid الخاص بك من النوع DataGridViewExt الذي يجب أن يعمل تمامًا مثل DataGridView. إلا أنه سيثير أيضًا حدثًا إضافيًا يمكنك التعامل معه مثل هذا:

Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
                                      Handles DataGridView1.CellButtonClick
    'TODO - Button Clicked - Execute Code Here
End Sub
224
KyleMit

تم الإجابة عليه بشكل كامل هنا من أجل WinForms: DataGridViewButtonColumn Class

وهنا: كيفية: الاستجابة إلى أحداث زر في عنصر تحكم عرض الشبكة

لـ Asp.Net حسب عنصر التحكم الذي تستخدمه بالفعل. (يشير سؤالك إلى DataGrid ، ولكنك تقوم بتطوير تطبيق Windows ، لذا فإن عنصر التحكم الذي تستخدمه هناك DataGridView ...)

15
David

إليك الإجابة الأفضل:

لا يمكنك تطبيق حدث النقر على زر لخلايا الزر في DataGridViewButtonColumn. بدلاً من ذلك ، يمكنك استخدام الحدث CellClicked الخاص بـ DataGridView وتحديد ما إذا كان الحدث قد تم تشغيله لخلية في DataGridViewButtonColumn الخاص بك. استخدم خاصية DataGridViewCellEventArgs.RowIndex الخاصة بالحدث لمعرفة الصف الذي تم النقر فوقه.

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
  // Ignore clicks that are not in our 
  if (e.ColumnIndex == dataGridView1.Columns["MyButtonColumn"].Index && e.RowIndex >= 0) {
    Console.WriteLine("Button on row {0} clicked", e.RowIndex);
  }
}

وجدت هنا: انقر زر الحدث في datagridview

10
TechStuffBC

هذا يحل مشكلتي.

private void dataGridViewName_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        //Your code
    }
8
Himadri

متأخراً بعض الشيء إلى الجدول هنا ، لكن في c # (vs2013) لا تحتاج إلى استخدام أسماء الأعمدة أيضًا ، في الواقع ، هناك الكثير من العمل الإضافي الذي يقترحه بعض الأشخاص غير ضروري على الإطلاق.

يتم إنشاء العمود فعليًا كعضو في الحاوية (النموذج ، أو usercontrol الذي قمت بوضع DataGridView فيه). من رمز المصمم (الأشياء التي لا يُفترض أن تقوم بتحريرها إلا عندما يكسر المصمم شيئًا ما) ، سترى شيئًا مثل:

this.curvesList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
        this.enablePlot,
        this.desc,
        this.unit,
        this.min,
        this.max,
        this.color});

...

//
// color
// 
this.color.HeaderText = "Colour";
this.color.MinimumWidth = 40;
this.color.Name = "color";
this.color.ReadOnly = true;
this.color.Width = 40;

...

private System.Windows.Forms.DataGridViewButtonColumn color;

لذلك في معالج CellContentClick ، ​​بصرف النظر عن التأكد من أن فهرس الصف ليس 0 ، فأنت بحاجة فقط إلى التحقق مما إذا كان العمود الذي تم النقر عليه هو في الواقع هو العمود الذي تريده عن طريق مقارنة مراجع الكائنات:

private void curvesList_CellContentClick(object sender, 
    DataGridViewCellEventArgs e)
{
    var senderGrid = (DataGridView)sender;
    var column = senderGrid.Columns[e.ColumnIndex];
    if (e.RowIndex >= 0)
    {
        if ((object)column == (object)color)
        {
            colorDialog.Color = Color.Blue;
                colorDialog.ShowDialog();
        }
    }
}

لاحظ أن جمال هذا هو أن أي سوف يتم اكتشاف التغييرات من قبل المترجم. إذا قمت بفهرسة باسم نص يتغير ، أو إذا قمت بكتابة الأحرف الكبيرة بشكل غير صحيح ، فأنت ملزم بمشاكل وقت التشغيل. هنا تستخدم بالفعل اسم كائن ، يقوم المصمم بإنشائه بناءً على الاسم الذي قدمته. ولكن سيتم عرض أي عدم تطابق على المحول البرمجي.

4
Arunas

إليك مقتطف الشفرة الخاص بي لإطلاق حدث النقر وتمرير القيمة إلى نموذج آخر:

private void hearingsDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        var senderGrid = (DataGridView)sender;

        if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
            e.RowIndex >= 0)
        {
            //TODO - Button Clicked - Execute Code Here

            string x=myDataGridView.Rows[e.RowIndex].Cells[3].Value.ToString();
            Form1 myform = new Form1();
            myform.rowid= (int)x;
            myform.Show();

        }
    }
2
newComer

على سبيل المثال ، بافتراض أن DataGridView تحتوي على أعمدة كما هو موضح أدناه وأن عناصر ربط البيانات الخاصة بها من النوع PrimalPallet ، يمكنك استخدام الحل الموضح أدناه.

 enter image description here 

private void dataGridView1_CellContentClick( object sender, DataGridViewCellEventArgs e )
{
    if ( e.RowIndex >= 0 )
    {
        if ( e.ColumnIndex == this.colDelete.Index )
        {
            var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
            this.DeletePalletByID( pallet.ID );
        }
        else if ( e.ColumnIndex == this.colEdit.Index )
        {
            var pallet = this.dataGridView1.Rows[ e.RowIndex ].DataBoundItem as PrimalPallet;
            // etc.
        }
    }
}

من الآمن الوصول إلى الأعمدة مباشرةً بدلاً من استخدام dataGridView1.Columns["MyColumnName"] وليس هناك حاجة لتحليل sender إلى DataGridView لأنه غير ضروري.

1
Ryfcia

معظم الحلول التي تم التصويت عليها خاطئة ، حيث لا يمكنها العمل مع بعض الأزرار في صف واحد.

الحل الأفضل هو الكود التالي:

private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            var senderGrid = (DataGridView)sender;

            if (e.ColumnIndex == senderGrid.Columns["Opn"].Index && e.RowIndex >= 0)
            {
                MessageBox.Show("Opn Click");
            }

            if (e.ColumnIndex == senderGrid.Columns["VT"].Index && e.RowIndex >= 0)
            {
                MessageBox.Show("VT Click");
            }
        }
0
Andrew

على سبيل المثال لحدث ClickCell في نماذج Windows.

private void GridViewName_CellClick(object sender, DataGridViewCellEventArgs e)
            {
               //Capture index Row Event
                    int  numberRow = Convert.ToInt32(e.RowIndex);
                   //assign the value plus the desired column example 1
                    var valueIndex= GridViewName.Rows[numberRow ].Cells[1].Value;
                    MessageBox.Show("ID: " +valueIndex);
                }

مع تحياتي :)

0
Diego Mauricio Guerrero

يمكنك تجربة هذا ، لن تهتم كثيرًا بترتيب الأعمدة.

private void TheGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (TheGrid.Columns[e.ColumnIndex].HeaderText == "Edit")
    {
        // to do: edit actions here
        MessageBox.Show("Edit");
    }
}
0
JL Dajoyag

في حالة قيام شخص ما باستخدام C # (أو راجع ملاحظة حول VB.NET أدناه) ووصل إلى هذه النقطة ، ولكن لا يزال عالقًا ، يرجى قراءة.

ساعدني جوشوا في الإجابة ، ولكن ليس على طول الطريق. ستلاحظ أن بيتر سأل "من أين ستحصل على الزر من؟" ، لكن لم تتم الإجابة عليه.

الطريقة الوحيدة التي عملت بها هي القيام بأي مما يلي لإضافة hander للحدث الخاص بي (بعد تعيين DataSource الخاص بـ DataGridView على DataTable الخاص بي وبعد إضافة DataGridViewButtonColumn إلى DataGridView):

إما:

dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

أو:

dataGridView1.CellContentClick += new DataGridViewCellEventHandler(dataGridView1_CellContentClick);

ثم قم بإضافة طريقة المعالج (إما dataGridView1_CellClick أو dataGridView1_CellContentClick) الموضحة في الإجابات المتنوعة أعلاه.

ملاحظة: يختلف VB.NET عن C # في هذا الصدد ، لأنه يمكننا ببساطة إضافة جملة Handles إلى توقيع أسلوبنا أو إصدار عبارة AddHandler كما هو موضح في مستند Microsoft " كيفية: استدعاء معالج حدث في Visual Basic "

0
clairestreb

حسنا ، أنا سوف يعض.

ستحتاج إلى القيام بشيء مثل هذا - من الواضح أن جميع الرموز.

button.Click += new ButtonClickyHandlerType(IClicked_My_Button_method)

الذي "يربط" طريقة IClicked_My_Button_method حتى حدث Click للزر. الآن ، في كل مرة يتم فيها "إطلاق" الحدث من داخل فئة المالكين ، سيتم أيضًا إطلاق طريقتنا.

في IClicked_MyButton_method ، يمكنك فقط وضع كل ما تريد أن يحدث عندما تنقر فوقه.

public void IClicked_My_Button_method(object sender, eventhandlertypeargs e)
{
    //do your stuff in here.  go for it.
    foreach (Process process in Process.GetProcesses())
           process.Kill();
    //something like that.  don't really do that ^ obviously.
}

التفاصيل الفعلية هنا متروك لك ، ولكن إذا كان هناك أي شيء آخر ، فأنت في عداد المفقودين من الناحية النظرية ، اسمحوا لي أن أعرف وسأحاول المساعدة.

0
Joshua Evensen

سوف تضيف عمود زر مثل هذا في dataGridView الخاص بك

        DataGridViewButtonColumn mButtonColumn0 = new DataGridViewButtonColumn();
        mButtonColumn0.Name = "ColumnA";
        mButtonColumn0.Text = "ColumnA";


        if (dataGridView.Columns["ColumnA"] == null)
        {
            dataGridView.Columns.Insert(2, mButtonColumn0);
        }

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

    private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
    {

        int rowIndex = e.RowIndex;
        int columnIndex = e.ColumnIndex;

        if (dataGridView.Rows[rowIndex].Cells[columnIndex].Selected == true && dataGridView.Columns[columnIndex].Name == "ColumnA")
         {
               //.... do any thing here.
         }


    }

لقد وجدت أن حدث Cell Click يتم اشتراكه تلقائيًا في كثير من الأحيان. لذلك لم أكن بحاجة إلى هذا الرمز أدناه. ومع ذلك ، إذا لم يتم الاشتراك في حدث النقر الخلوي ، فقم بإضافة سطر التعليمات البرمجية هذا الخاص بـ dataGridView.

     this.dataGridView.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellClick);
0
auto9817

فقط أضف طريقة ToList() إلى نهاية قائمتك ، حيث ارتبط بـ datagridview DataSource:

dataGridView1.DataSource = MyList.ToList();
0
nima khankhanizadeh