কীভাবে ডেটাগ্রিডভিউ চেকবক্স ইভেন্ট পরিবর্তনটি সনাক্ত করবেন?


90

আমার একটি উইনফর্মস অ্যাপ্লিকেশন রয়েছে এবং যখন কোনও DataGridViewনিয়ন্ত্রণে এমবেড থাকা চেকবক্সটি চেক / চেক করা না থাকে তখন কিছু কোড ট্রিগার করতে চাই । প্রতিটি ইভেন্ট আমি চেষ্টা করেছিলাম

  1. ক্লিক করার সাথে সাথে ট্রিগারগুলি CheckBoxকিন্তু এর পরীক্ষিত রাষ্ট্রের পরিবর্তনের আগে বা
  2. ট্রিগারগুলি কেবল একবার CheckBoxতার ফোকাসটি হারাবে

চেক করা রাষ্ট্রের পরিবর্তনের পরপরই আমি এমন ইভেন্টটি আবিষ্কার করতে চাই না।


সম্পাদনা করুন:

আমি যেটি অর্জন করতে চাইছি তা হ'ল যখন CheckBoxএকটিতে চেক করা রাষ্ট্রের DataGridViewপরিবর্তন হয়, তখন অন্য দুটি এর ডেটা DataGridViewপরিবর্তিত হয়। তবুও আমি সমস্ত ইভেন্টগুলি ব্যবহার করেছি, অন্যান্য গ্রিডের ডেটা কেবলমাত্র CheckBoxপ্রথম DataGridViewলস ফোকাসের পরে পরিবর্তিত হয় ।


4
আপনি CurrentCellDirtyStateChangedইভেন্ট চেক করেছেন ?
যোগরাজ গুপ্ত 10 ই

তবুও কেবল তখনই কার্যকর করা হয় যখন ব্যবহারকারী ঘর ছেড়ে চলে যায়।
পিজেডাব্লু

4
এখানে এই দুটিই MSDN নিবন্ধ: msdn.microsoft.com/en-us/library/... অনুরূপ কিন্তু Killercam এর উত্তর একটু ভিন্ন
ডেভিড হল

উত্তর:


96

হ্যান্ডেল করতে DatGridViewগুলি CheckedChangedইভেন্টে প্রথম পেতে হবে CellContentClickআগুন (যা নেই CheckBoxস্প্যানিশ ভাষায় বর্তমান অবস্থা!) তারপর কল CommitEdit। এর ফলে CellValueChangedঘটনাকে আগুন লাগিয়ে দেবে যা আপনি নিজের কাজটি করতে ব্যবহার করতে পারেন। এটি মাইক্রোসফ্ট দ্বারা একটি তদারকি । নীচের মতো কিছু করুন ...

private void dataGridViewSites_CellContentClick(object sender, 
    DataGridViewCellEventArgs e)
{
    dataGridViewSites.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

/// <summary>
/// Works with the above.
/// </summary>
private void dataGridViewSites_CellValueChanged(object sender, 
    DataGridViewCellEventArgs e)
{
    UpdateDataGridViewSite();
}

আশা করি এটা কাজে লাগবে.

পিএস এই নিবন্ধটি দেখুন https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentseldirtystatechanged(vvv.1.110).aspx


4
এটি একটি ভাল সমাধান কিন্তু কাজ ব্যবহারকারী বেশ কয়েকবার ক্লিক করে, একটি বিকল্প নীচের পোস্ট করা হয়েছে না stackoverflow.com/questions/11843488/...
56ka

4
আমি ডাবল ক্লিক সমস্যার জন্য এই সমাধানটি ব্যবহার না করার জন্য অত্যন্ত পরামর্শ দিচ্ছি। এন্ডএডিট () ফাংশনটি কল করা প্রয়োজন ... @ 56ka থেকে লিঙ্কটি সন্ধান করুন এবং নিবন্ধের লিঙ্কটিতে ক্লিক করুন!
লুক

4
আমি এই সমাধানটিতে বেশি দিন ব্যয় করি নি এবং যদি @ 56ka এর সমাধানটি আরও ভাল হয় তবে দুর্দান্ত। যাইহোক, আমি নিশ্চিত নই যে DataGridViewCheckBoxএটিকে ডাবল ক্লিক করার বিষয়ে সমস্ত গোলমাল কী। এটি ডাব্লুপিএফ নয় এবং নিয়ন্ত্রণে ডাবল ক্লিক করা কোনও ডেটা বাঁধাই করছে না, এটি উইনফোর্স For ডাবল ক্লিক ক্লিক করে নিয়ন্ত্রণটি দৃশ্যত আপডেট নাও করতে পারে তবে এটি কিছুতেই ভাঙবে না এবং এই ক্ষেত্রে সম্ভবত নীচের সমাধানটি আরও ভাল। ধন্যবাদ
মুনকনাইট

যদি আপনার কাছ থেকে একই কোড যোগ করবেন তারা এই ঠিকভাবে কাজ CellContentClickমধ্যে CellContentDoubleClickহিসাবে ভাল। CellMouseUpসেল নির্বাচন করা হলেও চেকবক্স ক্লিক করা না থাকলেও তা আগুন ধরিয়ে দেবে - যা পছন্দসই আচরণ নয়।
টর্পিড শিকার

89

আমি @ কিলারক্যামের কাজের সমাধান খুঁজে পেয়েছি তবে ব্যবহারকারী খুব দ্রুত ডাবল ক্লিক করলে কিছুটা দ্বিধায় ছিল। নিশ্চিত না অন্যের ক্ষেত্রেও এটি পাওয়া গেছে কিনা। আমি অন্য সমাধান পাওয়া এখানে

এটি ডেটাগ্রিড CellValueChangedএবং ব্যবহার করে CellMouseUp। চ্যাংহং এটি ব্যাখ্যা করে

"এর কারণ হ'ল অনকেলভ্যালু চ্যাঞ্জড ইভেন্টটি ডেটাগ্রিডভিউ ভেবে না দেখলে আপনি সম্পাদনা সম্পন্ন করেছেন On একটি চেকবক্সের জন্য বুদ্ধিমান করুন] "।

এখানে এটি তার উদাহরণ থেকে কার্যকর হয়:

private void myDataGrid_OnCellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        // Handle checkbox state change here
    }
}

এবং চেকবাক্সটি বলার কোডটি এটি ক্লিক করা হলে সম্পাদনা সম্পন্ন হয়, ব্যবহারকারী ক্ষেত্রটি না ছেড়ে অপেক্ষা করার পরিবর্তে:

private void myDataGrid_OnCellMouseUp(object sender,DataGridViewCellMouseEventArgs e)
{
    // End of edition on each click on column of checkbox
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        myDataGrid.EndEdit();
    }
}

সম্পাদনা করুন: একটি ডাবলক্লিক ইভেন্টটিকে মাউসআপ ইভেন্ট থেকে পৃথক চিকিত্সা করা হয়। যদি একটি ডাবলিক্লিক ইভেন্ট সনাক্ত করা থাকে তবে অ্যাপ্লিকেশনটি প্রথম মাউসআপ ইভেন্টটিকে পুরোপুরি উপেক্ষা করবে। এই যুক্তিটি মাউসআপ ইভেন্টের পাশাপাশি সেলডুবলক্লিক ইভেন্টে যুক্ত করা দরকার:

private void myDataGrid_OnCellDoubleClick(object sender,DataGridViewCellEventArgs e)
{
    // End of edition on each click on column of checkbox
    if (e.ColumnIndex == myCheckBoxColumn.Index && e.RowIndex != -1)
    {
        myDataGrid.EndEdit();
    }
}

4
আমি প্রতিক্রিয়াকারী দ্বারা উল্লিখিত ডাবল-ক্লিক সমস্যার মধ্যে দৌড়েছি এবং এইটি সঠিকভাবে পরিচালনা করার ক্ষেত্রে প্রথম সমাধানের চেয়ে অনেক ভাল কাজ করেছে।
স্টিভ ফার্গুসন

4
আমি ডাবল-ক্লিক সমস্যার মধ্যেও ছুটে এসেছি এবং এই সমাধানটি এটি ঠিক করে দিয়েছে।
ক্রিস সি

'এখানে' বোতামটি ক্লিক করুন এবং নিবন্ধটি দেখুন। আমার ডাবল ক্লিকের সাথে একই সমস্যা ছিল।
লুক

4
আপনি যদি স্পেস বার দিয়ে টগল টগল করেন?
হাফগয়ার

4
'ফিক্স' থেকে spacebar ইস্যু করার জন্য, আমি সেট KeyPreviewফর্ম এবং যখন উপর সত্যতে e.KeyCode == Keys.Space, সেট e.Handled = true। অন্য কথায়, আমি কেবল কীবোর্ড সম্পাদনা অক্ষম করেছি।
হাফগ্গার

9

jsturtevants এর সমাধান দুর্দান্ত কাজ করেছে। যাইহোক, আমি এন্ডএডিট ইভেন্টে প্রসেসিংয়ের বিকল্পটি বেছে নিয়েছি। আমি এই পদ্ধতির পছন্দ করি (আমার আবেদনে) কারণ সেলভিয়েল চেঞ্জড ইভেন্টের বিপরীতে, আপনি গ্রিডটি পপুলেটিং করার সময় এন্ডএডিট ইভেন্টটি জ্বলে না।

এখানে আমার কোড (যার অংশ jsturtevan থেকে চুরি হয়েছে:

private void gridCategories_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
    {
        //do some stuff
    }
}



private void gridCategories_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex == gridCategories.Columns["AddCategory"].Index)
    {
        gridCategories.EndEdit();
    }
}

4
উত্তম উত্তর, তবে এটির CellContentClickপরিবর্তে ব্যবহার করা পছন্দনীয় CellMouseUpকারণ ব্যবহারকারী যখন ঘরের মধ্যে কোথাও ক্লিক করেন তবে পূর্ববর্তীটি তখনই ডাকা হবে যখন চেকবক্সটি ক্লিক করা হয় কেবল তখনই বলা হয়।
জেমি কিটসন

6

এটি কীবোর্ড অ্যাক্টিভেশন পরিচালনা করে।

    private void dgvApps_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if(dgvApps.CurrentCell.GetType() == typeof(DataGridViewCheckBoxCell))
        {
            if (dgvApps.CurrentCell.IsInEditMode)
            {
                if (dgvApps.IsCurrentCellDirty)
                {
                    dgvApps.EndEdit();
                }
            }
        }
    }


    private void dgvApps_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
          // handle value changed.....
    }

5

এখানে কিছু কোড রয়েছে:

private void dgvStandingOrder_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (dgvStandingOrder.Columns[e.ColumnIndex].Name == "IsSelected" && dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
    {
        bool isChecked = (bool)dgvStandingOrder[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
        if (isChecked == false)
        {
            dgvStandingOrder.Rows[e.RowIndex].Cells["Status"].Value = "";
        }
        dgvStandingOrder.EndEdit();
    }
}

private void dgvStandingOrder_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{

    dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
    {
        dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

4
এই উত্তরে সঠিক উত্তর রয়েছে যা মাউস এবং কীবোর্ড উভয় কথোপকথন এবং ঘর ছাড়াই পুনরাবৃত্তি ইন্টারঅ্যাকশন পরিচালনা করে। তবে শুধুমাত্র শেষ হ্যান্ডলারের প্রয়োজন - কল CommitEditকরা CurrentCellDirtyStateChangedসম্পূর্ণ সমাধান।
বেন ভয়েগট

4

আমার কোড, কিলারক্যাম'সওয়ার অনুসরণ করছে

private void dgvProducts_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        dgvProducts.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }

এবং :

private void dgvProducts_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
        if (dgvProducts.DataSource != null)
        {
            if (dgvProducts.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "True")
            {
                //do something
            }
            else
            {
               //do something
            }
        }
    }

2

এটি সেলটি সম্পাদনা করার বিষয়েই রয়েছে, সেলটি সমস্যাটি আসলে সম্পাদিত হয়নি, সুতরাং আপনার চেক বাক্সটি ক্লিক করার পরে ইভেন্টটি পেতে সেল বা সারি পরিবর্তনগুলি সংরক্ষণ করতে হবে যাতে আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

datagridview.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange)

এটির সাথে আপনি এটি অন্য কোনও ইভেন্টের সাথেও ব্যবহার করতে পারেন।


2

আমি এই সমস্যার সহজ উত্তর পেয়েছি। আমি কেবল বিপরীত যুক্তি ব্যবহার করি। কোডটি ভিবিতে রয়েছে তবে এটি সি # এর চেয়ে আলাদা নয়।

 Private Sub DataGridView1_CellContentClick(sender As Object, e As 
 DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

    Dim _ColumnIndex As Integer = e.ColumnIndex
    Dim _RowIndex As Integer = e.RowIndex

    'Uses reverse logic for current cell because checkbox checked occures 
     'after click
    'If you know current state is False then logic dictates that a click 
     'event will set it true
    'With these 2 check boxes only one can be true while both can be off

    If DataGridView1.Rows(_RowIndex).Cells("Column2").Value = False And 
       DataGridView1.Rows(_RowIndex).Cells("Column3").Value = True Then
        DataGridView1.Rows(_RowIndex).Cells("Column3").Value = False
    End If

    If DataGridView1.Rows(_RowIndex).Cells("Column3").Value = False And 
    DataGridView1.Rows(_RowIndex).Cells("Column2").Value = True Then
        DataGridView1.Rows(_RowIndex).Cells("Column2").Value = False
    End If


End Sub

এ সম্পর্কে সেরা জিনিসগুলির মধ্যে একাধিক ইভেন্টের প্রয়োজন নেই।


1

আমার জন্য যা কাজ করেছে তার CurrentCellDirtyStateChangedসাথে মিল ছিলdatagridView1.EndEdit()

private void dataGridView1_CurrentCellDirtyStateChanged( object sender, EventArgs e ) {
    if ( dataGridView1.CurrentCell is DataGridViewCheckBoxCell ) {
        DataGridViewCheckBoxCell cb = (DataGridViewCheckBoxCell)dataGridView1.CurrentCell;
        if ( (byte)cb.Value == 1 ) {
            dataGridView1.CurrentRow.Cells["time_loadedCol"].Value = DateTime.Now.ToString();
        }
    }
    dataGridView1.EndEdit();
}

1

কোডটি ডাটাগ্রিডভিউতে লুপ করবে এবং চেকবক্স কলাম চেক করা আছে কিনা তা পরীক্ষা করবে

private void dgv1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex == 0 && e.RowIndex > -1)
    {
        dgv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        var i = 0;
        foreach (DataGridViewRow row in dgv1.Rows)
        {
            if (Convert.ToBoolean(row.Cells[0].Value))
            {
                i++;
            }
        }

        //Enable Button1 if Checkbox is Checked
        if (i > 0)
        {
            Button1.Enabled = true;
        }
        else
        {
            Button1.Enabled = false;
        }
    }
}

1

ইভেন্টটিতে সেলস কনটেন্ট ক্লিক আপনি এই কৌশলটি ব্যবহার করতে পারেন:

private void myDataGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{    
    if (e.ColumnIndex == 2)//set your checkbox column index instead of 2
    {   //When you check
        if (Convert.ToBoolean(myDataGrid.Rows[e.RowIndex].Cells[2].EditedFormattedValue) == true)
        {
            //EXAMPLE OF OTHER CODE
            myDataGrid.Rows[e.RowIndex].Cells[5].Value = DateTime.Now.ToShortDateString();

            //SET BY CODE THE CHECK BOX
            myDataGrid.Rows[e.RowIndex].Cells[2].Value = 1;
        }
        else //When you decheck
        {
            myDataGrid.Rows[e.RowIndex].Cells[5].Value = String.Empty;

            //SET BY CODE THE CHECK BOX
            myDataGrid.Rows[e.RowIndex].Cells[2].Value = 0;
        }
    }
}

1

আমি এখান থেকে কিছু উত্তর চেষ্টা করেছি, তবে আমার সর্বদা কিছুটা সমস্যা ছিল (যেমন ডাবল ক্লিক বা কীবোর্ড ব্যবহার করে)। সুতরাং, আমি তাদের কয়েকটি সংযুক্ত করেছি এবং একটি সামঞ্জস্যপূর্ণ আচরণ পেয়েছি (এটি নিখুঁত নয়, তবে সঠিকভাবে কাজ করে)।

void gridView_CellContentClick(object sender, DataGridViewCellEventArgs e) {
  if(gridView.CurrentCell.GetType() != typeof(DataGridViewCheckBoxCell))
    return;
  if(!gridView.CurrentCell.IsInEditMode)
    return;
  if(!gridView.IsCurrentCellDirty)
    return;
  gridView.EndEdit();
}

void gridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) {
  if(e.ColumnIndex == gridView.Columns["cFlag"].Index && e.RowIndex >= 0)
    gridView.EndEdit();
}

void gridView_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
  if(e.ColumnIndex != gridView.Columns["cFlag"].Index || e.RowIndex < 0)
    return;

  // Do your stuff here.

}

0

ডিভ এক্সপ্রেস অ্যাক্সট্রাগ্রিড ব্যবহার করার জন্য এটি করার জন্য, এখানে বর্ণিত হিসাবে সম্পর্কিত রিপোজিটরি আইটেমের সম্পাদনাভ্যালু চেঞ্জড ইভেন্টটি পরিচালনা করা প্রয়োজন । পরিবর্তিত মান পোস্ট করা হয়েছে তা নিশ্চিত করার জন্য গ্রিডভিউ 1.পোস্টএডিটর () পদ্ধতিতে কল করাও গুরুত্বপূর্ণ। এখানে একটি বাস্তবায়ন:

        private void RepositoryItemCheckEdit1_EditValueChanged(object sender, System.EventArgs e)
        {
            gridView3.PostEditor();

            var isNoneOfTheAboveChecked = false;

            for (int i = 0; i < gridView3.DataRowCount; i++)
            {
                if ((bool) (gridView3.GetRowCellValue(i, "NoneOfTheAbove")) && (bool) (gridView3.GetRowCellValue(i, "Answer")))
                {
                    isNoneOfTheAboveChecked = true;
                    break;
                }
            }

            if (isNoneOfTheAboveChecked)
            {
                for (int i = 0; i < gridView3.DataRowCount; i++)
                {
                    if (!((bool)(gridView3.GetRowCellValue(i, "NoneOfTheAbove"))))
                    {
                        gridView3.SetRowCellValue(i, "Answer", false);
                    }
                }
            }
        }

নোট করুন যেহেতু অক্সট্রাগ্রিড একটি এনুমিউরেটর সরবরাহ করে না, সারিগুলিতে পুনরাবৃত্তি করার জন্য লুপের জন্য একটি ব্যবহার করা প্রয়োজন।


0

কক্ষের মান পরিবর্তনের পরে ফোকাস সরানো মানগুলি ডেটাগ্রিডভিউতে আপডেট করার অনুমতি দেয়। কারেন্টসেলটি নালায় সেট করে ফোকাস সরান।

private void DataGridView1OnCellValueChanged(object sender, DataGridViewCellEventArgs dataGridViewCellEventArgs)
{
    // Remove focus
    dataGridView1.CurrentCell = null;
    // Put in updates
    Update();
}

private void DataGridView1OnCurrentCellDirtyStateChanged(object sender, EventArgs eventArgs)
{
    if (dataGridView1.IsCurrentCellDirty)
    {
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }

}

0

আপনি চেকবক্সটিতে ক্লিক করার সাথে সাথে সেলটি মান প্রতিশ্রুতি দিতে বাধ্য করতে পারেন এবং তারপরে সেলভ্যালু চেঞ্জড ইভেন্টটি ধরতে পারেন । CurrentCellDirtyStateChanged হিসাবে আপনি চেকবক্সটিতে ক্লিক করুন তাড়াতাড়ি দাবানল।

নিম্নলিখিত কোডটি আমার পক্ষে কাজ করে:

private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        SendKeys.Send("{tab}");
    }

তারপরে আপনি সেলভ্যালু চেঞ্জড ইভেন্টে আপনার কোডটি .োকাতে পারেন


0

বেন ভয়েগট উপরের মন্তব্য-উত্তরে সর্বোত্তম সমাধানটি পেয়েছেন:

private void dgvStandingOrder_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvStandingOrder.CurrentCell is DataGridViewCheckBoxCell)
        dgvStandingOrder.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

সিরিয়াসলি, এটি আপনার প্রয়োজন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.