2010-05-21 16 views
6

मैं DataGridView को चेकबॉक्सों की एक श्रृंखला के साथ क्षैतिज और लंबवत लेबल के साथ बना रहा हूं। कोई भी लेबल जो समान हैं, चेकबॉक्स निष्क्रिय होंगे, और मैं केवल प्रत्येक संयोजन के लिए मान्य होने के लिए दो "चेक" में से एक चाहता हूं। निम्नलिखित स्क्रीनशॉट दिखाता है कि मेरे पास क्या है: DataGridView http://i46.tinypic.com/2e4m3pz.pngडेटाग्रिड व्यू चेकबॉक्स घटनाएं

निचले आधे भाग पर चेक किए गए कुछ भी, मैं ऊपरी भाग पर संयुक्त राष्ट्र की जांच करना चाहता हूं। तो यदि [quux, स्पैम] (या [7, 8] शून्य-आधारित समन्वय के लिए) चेक किया गया है, तो मुझे [स्पैम, quux] ([8, 7]) अन-चेक किया गया है। क्या मैं अब तक है निम्नलिखित है:

dgvSysGrid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; 
    dgvSysGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; 
    string[] allsysNames = { "heya", "there", "lots", "of", "names", "foo", "bar", "quux", "spam", "eggs", "bacon" }; 

    // Add a column for each entry, and a row for each entry, and mark the "diagonals" as readonly 
    for (int i = 0; i < allsysNames.Length; i++) 
    { 
     dgvSysGrid.Columns.Add(new DataGridViewCheckBoxColumn(false)); 
     dgvSysGrid.Columns[i].HeaderText = allsysNames[i]; 
     dgvSysGrid.Rows.Add(); 
     dgvSysGrid.Rows[i].HeaderCell.Value = allsysNames[i]; 
     // Mark all of the "diagonals" as unable to change 
     DataGridViewCell curDiagonal = dgvSysGrid[i, i]; 
     curDiagonal.ReadOnly = true; 
     curDiagonal.Style.BackColor = Color.Black; 
     curDiagonal.Style.ForeColor = Color.Black; 
    } 

    // Hook up the event handler so that we can change the "corresponding" checkboxes as needed 
    //dgvSysGrid.CurrentCellDirtyStateChanged += new EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged); 
    dgvSysGrid.CellValueChanged += new DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged); 

} 

void dgvSysGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e) 
{ 
    Point cur = new Point(e.ColumnIndex, e.RowIndex); 

    // Change the diagonal checkbox to the opposite state 
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y]; 
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X]; 
    if ((bool)(curCell.Value) == true) 
    { 
     diagCell.Value = false; 
    } 
    else 
    { 
     diagCell.Value = true; 
    } 
} 

/// <summary> 
/// Change the corresponding checkbox to the opposite state of the current one 
/// </summary> 
/// <param name="sender"></param> 
/// <param name="e"></param> 
void dgvSysGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
{ 
    Point cur = dgvSysGrid.CurrentCellAddress; 

    // Change the diagonal checkbox to the opposite state 
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y]; 
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X]; 
    if ((bool)(curCell.Value) == true) 
    { 
     diagCell.Value = false; 
    } 
    else 
    { 
     diagCell.Value = true; 
    } 
} 

समस्या आता है कि सेल मूल्य हमेशा "के पीछे एक" प्रतीत हो रहा है बदल गया है, जहां आप वास्तव में अगर मैं CellValueChanged घटना का उपयोग क्लिक करें, और मुझे यकीन है कि नहीं कर रहा हूँ वर्तमान सेल कैसे प्राप्त करें यदि मैं "गंदे" राज्य में हूं क्योंकि curCell एक शून्य के रूप में आता है (वर्तमान सेल पता किसी भी तरह गलत है, लेकिन मैंने कोशिश नहीं की और उस मान को प्राप्त नहीं किया) जिसका अर्थ है कि पथ isn ' बिल्कुल काम नहीं कर रहा हूँ।

असल में, मुझे सही बूलियन मूल्य के साथ "दाएं" पता कैसे मिलता है ताकि मेरा फ़्लिपिंग एल्गोरिदम काम करेगा?

उत्तर

16

अंततः, यह CurrentCellDirtyStateChanged ऐसा होने की अवस्था में था, लेकिन आप सही तरीके से यह करने के लिए की जरूरत है। और सही तरीका MSDN है, हालांकि यह पहली नज़र में समझ में नहीं आता है।

ऊपर से एक टुकड़ा है, और क्या मैं अंत में किया था नीचे है:

// Hook up the event handler so that we can change the "corresponding" checkboxes as needed 
    dgvSysGrid.CurrentCellDirtyStateChanged += new EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged); 
    dgvSysGrid.CellValueChanged += new DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged); 

} 

void dgvSysGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e) 
{ 
    Point cur = new Point(e.ColumnIndex, e.RowIndex); 

    // Change the diagonal checkbox to the opposite state 
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y]; 
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X]; 
    if ((bool)(curCell.Value) == true) 
    { 
     diagCell.Value = false; 
    } 
    else 
    { 
     diagCell.Value = true; 
    } 
} 

void dgvSysGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
{ 
    if (dgvSysGrid.IsCurrentCellDirty) 
    { 
     dgvSysGrid.CommitEdit(DataGridViewDataErrorContexts.Commit); 
    } 
} 

असल में, यह सब क्या हो रहा है CurrentCellDirtyStateChanged घटना CellValueChanged ईवेंट ट्रिगर करता है, और बस इतना ही। यदि आप बस CellValueChanged ईवेंट संलग्न करते हैं, तो यह सेल छोड़ने के बाद ही ट्रिगर होता है। मुझे नहीं पता क्यों बिल्कुल (यह एक चेकबॉक्स पर विचार कर रहा है, क्या यह तुरंत "किया" नहीं है?), लेकिन ऐसा ही होता है। और ऊपर दिए गए कोड के रूप में कोड, उस पर क्लिक करते समय चेक बॉक्स में परिवर्तन सही हो जाते हैं। तो यह काम करता है।

+0

हाँ !! ... मेरी खोज खत्म हो गई है ... अब मैं खुशी से बाद में रह सकता हूं। धन्यवाद। – zmaster

2

आप CellValidating ईवेंट का उपयोग कर सकते हैं और e.FormattedValue में बदले गए मूल्य होंगे। यदि आप कुछ चेक करते हैं, और मान को अपडेट नहीं करना चाहते हैं, तो ई। कैंसल को सत्य पर सेट करें।

यहाँ FormattedValue पेज से उदाहरण है:

private void dataGridView1_CellValidating(object sender, 
    DataGridViewCellValidatingEventArgs e) 
{ 
    dataGridView1.Rows[e.RowIndex].ErrorText = ""; 
    int newInteger; 

    // Don't try to validate the 'new row' until finished 
    // editing since there 
    // is not any point in validating its initial value. 
    if (dataGridView1.Rows[e.RowIndex].IsNewRow) { return; } 
    if (!int.TryParse(e.FormattedValue.ToString(), 
     out newInteger) || newInteger < 0) 
    { 
     e.Cancel = true; 
     dataGridView1.Rows[e.RowIndex].ErrorText = "the value must be a non-negative integer"; 
    } 
} 
+0

दुर्भाग्य से यह काम नहीं करता है क्योंकि सेल सेलडाइडेटिंग घटना केवल तभी गोलीबारी कर रही है जब मैं सेल छोड़ देता हूं, न कि जब चेकबॉक्स क्लिक किया जाता है और राज्य स्विच करता है। –

0

सरल तकनीक मैंने पाया है: grid_CellContentClick

  • के लिए

    • रजिस्टर नीचे का उपयोग करके सेल के दोनों सभी पंक्तियों, या ईवेंट हैंडलर से सिर्फ पंक्ति की जांच करना। मेरे कोड को क्लिक की गई कोशिकाओं की पूरी स्थिति से एक डेटा मॉडल फिर से बनाने की आवश्यकता है।

    संपादित फ़ॉर्मेटेड वैल्यू सेल का "नया" मान है, और पढ़ने के लिए मूल्य है।

    var colNumber=0; 
    foreach (var row in grid.Rows) { 
        var dataGridViewCell = (DataGridViewCheckBoxCell)((DataGridViewRow)(row)).Cells[colNumber]; 
        if (dataGridViewCell.EditedFormattedValue) { 
         // This cell is now checked - do whatever you need to with the other cells 
        } 
    } 
    
  • संबंधित मुद्दे