2012-03-07 9 views
15

मैंने अपने डेटाग्रिड व्यू के लिए कॉम्बोबॉक्स कॉलम स्थापित किया है और इसके चयन योग्य मानों को एक गणना से सेट किया है। यह ज्यादातर काम करता है क्योंकि मैं निम्नलिखित अपवाद के साथ चाहूंगा।डेटाग्रिड व्यू कॉम्बोबॉक्स कॉलम: ड्रॉपडाउन से चयन के बाद सेल मान बदलें?

जब भी मैं ड्रॉपडाउन तीर पर क्लिक करता हूं और फिर enum मानों में से एक का चयन करता हूं, यह एक "मध्यवर्ती" स्थिति के प्रकार में रहता है जहां CellValueChanged ईवेंट ट्रिगर नहीं होता है। घटना के लिए मुझे किसी अन्य सेल या किसी अन्य नियंत्रण पर ध्यान केंद्रित करने की आवश्यकता है।

मेरे पास डेटाग्रिड व्यू के छोड़ने की घटना के लिए एक ईवेंट हैंडलर भी है जो यह सुनिश्चित करके सामग्री को मान्य करता है कि कोई सेल खाली नहीं है।

इसलिए, यदि मैं एक पंक्ति बनाता हूं और सभी कोशिकाओं को भरता हूं और (वर्तमान में रिक्त) कॉम्बोबॉक्स कॉलम पर आ जाता हूं, तो उसे एक मान में बदलें, और फिर रन बटन पर क्लिक करें; मेरा त्रुटि संवाद पॉप अप करता है क्योंकि कॉम्बोबॉक्स चयन "सहेजा नहीं गया" था।

मैं इसके आसपास कैसे हो सकता हूं? क्या कोई तरीका है कि ड्रॉप डाउन से मूल्य चुनने के बाद यह स्वचालित रूप से मान को "सेट" करता है?

धन्यवाद!

उत्तर

19

आप CurrentCellDirtyStateChanged घटना का उपयोग करें और के लिए मजबूर एक ग्रिड पर संपादित करने चाहिए:

private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
    { 
     dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 
    } 

आशा है कि यह मदद करता है!

+0

यह निश्चित रूप से किया गया था! धन्यवाद! – john

3

DataGridViewColumnCommitEdit को मजबूर करने से पहले का प्रकार यह जांच कर आयनडेन का जवाब बढ़ाएगा। यह अन्य DataGridViewColumn ऑब्जेक्ट्स को बहुत जल्दी से करने से रोक देगा।

dataGridView1.CurrentCellDirtyStateChanged += dataGridView1_CurrentCellDirtyStateChanged; 

    void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
    { 
     DataGridViewColumn col = dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex]; 
     if (col is DataGridViewComboBoxColumn) 
     { 
      dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 
     } 
    } 
0

यहाँ कैसे मैं इस मुद्दे

Private Sub dgvEcheancier_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dgvEcheancier.CurrentCellDirtyStateChanged 
     nbreClick += 1 
      With dgvEcheancier 
       Select Case .CurrentCell.ColumnIndex 
       Case 9 
        Dim col As DataGridViewComboBoxColumn = .Columns(9) 
        If TypeOf (col) Is DataGridViewComboBoxColumn Then 
         dgvEcheancier.CommitEdit(DataGridViewDataErrorContexts.Commit) 
         If nbreClick = 2 Then 
          MessageBox.Show("y" & "val=" & .CurrentCell.Value) 
          nbreClick = 0 
         End If 
        End If 

      End Select 
      End With 
+0

कृपया सी # टैग देखें। –

1

हल कुछ मामलों में है, मूल्य नहीं बने रहेंगे जब तक फोकस पूरी तरह से पंक्ति छोड़ दिया है। उस मामले में, समाप्त करने के लिए वर्तमान संपादन के लिए मजबूर करने का एकमात्र तरीका पूरी बाध्यकारी संदर्भ पर समाप्त करने है:

mGridView.CommitEdit(DataGridViewDataErrorContexts.Commit); 
mGridView.BindingContext[mGridView.DataSource].EndCurrentEdit(); // <<=== 

मैं इस टिप here पाया।

11

मैं स्तंभ प्रकार के बजाय सेल प्रकार की जांच करके मूप के उत्तर का विस्तार करूंगा।

dataGridView1.CurrentCellDirtyStateChanged += dataGridView1_CurrentCellDirtyStateChanged; 

void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
{ 
    if (CurrentCell is DataGridViewComboBoxCell) 
    { 
     dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit); 
     dataGridView1.EndEdit(); 
    } 
} 
0
void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
{ 
    dataGridView1.BeginEdit(true); 
    ComboBox cmbMiCtrl=(ComboBox)dataGridView1.EditingControl; 
    string Valor= cmbMiCtrl.Text; 
    dataGridView1.EndEdit(); 
} 
0

एक समस्या यह है कि मैंने देखा: GridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter;

0

मैं एक त्रुटि के लिए खोज के लिए दो घंटे की तरह खर्च क्योंकि मैं नोटिस नहीं किया था कि सेल मूल्य करता है: यदि आप चाहें तो यह काम नहीं करेगा सहेजा नहीं जाता है अगर यह defocused नहीं है, या कहने के लिए बेहतर है कि मैंने अभी देखा है कि सेल defocused नहीं है क्योंकि combobox बचत (बीटीएन घटना) जबकि बाहर whited। न केवल, संपादनऑन एंटर-मोड प्रचलित है कि काम के ऊपर दिखाए गए अधिकांश अन्य तरीकों से। EditOnEnter का उपयोग करने का कारण यह है कि जब आप DataGridViewComboBoxColumn का उपयोग करते हैं, तो आपको ड्रॉपडाउन खोलने के लिए दो बार क्लिक करना होगा यदि आप EditMnEnter पर EditMode सेट नहीं करते हैं।

this.dataGridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2; this.dataGridView.EndEdit(); this.dataGridView.EditMode = DataGridViewEditMode.EditOnEnter;

मुझे आशा है कि इस मदद करता है।मुझे दो घंटों तक आश्चर्य हुआ कि ऑब्जेक्ट में मूल्य एक जैसा नहीं है, फिर जीयूआई पर दिखाया गया है।

0

मैं पहले से ही हुई चर्चा के अनुवर्ती के रूप में अपना उत्तर जोड़ रहा हूं। मैं एक DataGridView बनाने की कोशिश कर रहा था जिसमें प्रति पंक्ति अलग comboboxes था। उन्हें एक क्लिक के लिए उत्तरदायी होना भी था। और, जब चयन किया गया था, तो पंक्ति में एक और कक्ष को combobox चयन के अनुसार बदला जाना आवश्यक था। चयन के तुरंत बाद परिवर्तन होने की आवश्यकता थी। ओपी की तरह मेरी मुख्य समस्या, बदलाव तब तक नहीं हुआ जब तक कि combobox फोकस खो गया।

तो, यहां डेटाग्रिड व्यू का एक पूर्ण कामकाजी उदाहरण है। मुझे इसे कम से कम ले जाना पड़ा क्योंकि एक ही समय में काम करने के लिए मेरी सभी आवश्यकताओं को मुश्किल बनाना था। कई एसओ पोस्ट इसे बनाने में चले गए, और मैं बाद में संदर्भों के साथ अपनी पोस्ट अपडेट कर दूंगा। लेकिन अब के लिए, यहां आता है ...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 

namespace TestDGV 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private Panel panel2; 
    private DataGridView TestGrid; 

    private void InitializeComponent() 
    { 
     this.panel2 = new System.Windows.Forms.Panel(); 
     this.SuspendLayout(); 
     // 
     // panel2 
     // 
     this.panel2.Dock = DockStyle.Fill; 
     this.panel2.Name = "panel2"; 
     this.panel2.TabIndex = 1; 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(661, 407); 
     this.Controls.Add(this.panel2); 
     this.Name = "Form1"; 
     this.Text = "Form1"; 
     this.Load += new System.EventHandler(this.Form1_Load); 
     this.ResumeLayout(false); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     //basic grid properties 
     TestGrid = new DataGridView(); 
     TestGrid.Dock = DockStyle.Fill; 
     TestGrid.AutoGenerateColumns = false; 
     TestGrid.Name = "TestGrid"; 
     TestGrid.ReadOnly = false; 
     TestGrid.EditMode = DataGridViewEditMode.EditOnEnter; 

     //Event handlers 
     TestGrid.DataBindingComplete += TestGrid_DataBindingComplete; 
     TestGrid.CurrentCellDirtyStateChanged += TestGrid_CurrentCellDirtyStateChanged; 
     TestGrid.CellValueChanged += TestGrid_CellValueChanged; 

     //columns 
     var textCol = new DataGridViewTextBoxColumn(); 
     textCol.HeaderText = "Text"; 
     textCol.Name = "Text"; 
     textCol.DataPropertyName = "Text"; 
     textCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; 
     TestGrid.Columns.Add(textCol); 

     var comboCol = new DataGridViewComboBoxColumn(); 
     comboCol.HeaderText = "ComboBox"; 
     comboCol.Name = "ComboBox"; 
     comboCol.AutoComplete = true; 
     comboCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; 
     TestGrid.Columns.Add(comboCol); 

     var resultCol = new DataGridViewTextBoxColumn(); 
     resultCol.HeaderText = "Result"; 
     resultCol.Name = "Result"; 
     resultCol.DataPropertyName = "Result"; 
     resultCol.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; 
     TestGrid.Columns.Add(resultCol); 

     //Bind the data 
     Datum.TestLoad(); 
     TestGrid.DataSource = Datum.Data; 

     panel2.Controls.Add(TestGrid); 
    } 

    void TestGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e) 
    { 
     if (e.RowIndex < 0 || e.ColumnIndex < 0) 
      return; 

     var row = TestGrid.Rows[e.RowIndex]; 
     var cell = row.Cells[e.ColumnIndex]; 
     if (cell is DataGridViewComboBoxCell) 
     { 
      var val = cell.Value as string; 
      var datum = row.DataBoundItem as Datum; 
      datum.Current = val; 
      row.Cells["Result"].Value = datum.Result; 
      TestGrid.InvalidateRow(e.RowIndex); 
     } 
    } 


    void TestGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
    { 
     if(TestGrid.CurrentCell is DataGridViewComboBoxCell) 
     { 
      TestGrid.CommitEdit(DataGridViewDataErrorContexts.Commit); 
      TestGrid.EndEdit(); 
     } 
    } 

    void TestGrid_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) 
    { 
     foreach (DataGridViewRow row in TestGrid.Rows) 
     { 
      var datum = row.DataBoundItem as Datum; 
      if (datum == null) 
       return; 

      var cell = row.Cells["ComboBox"] as DataGridViewComboBoxCell; 
      if (cell.DataSource == null) 
      { 
       cell.DisplayMember = "KeyDisplayValue"; 
       cell.ValueMember = "KeyValue"; 
       cell.DataSource = (row.DataBoundItem as Datum).Combo; 
       cell.Value = (row.DataBoundItem as Datum).Current; 
      } 
     } 
     TestGrid.DataBindingComplete -= TestGrid_DataBindingComplete; 
    } 

    public class Datum 
    { 
     public static void TestLoad() 
     { 
      var t1 = new Triplet[] { 
        new Triplet("1", "World", "Everyone"), 
        new Triplet("2", "Charlie", "Friend of Algernon"), 
        new Triplet("3", "Lester", "Phenomenal programmer"), 
      }; 
      var t2 = new Triplet[] { 
        new Triplet("1", "World", "Everyone"), 
        new Triplet("4", "Mary", "Wife of George Bailey"), 
        new Triplet("3", "Lester", "Phenomenal programmer"), 
      }; 
      Data.Add(new Datum("hello, ", t1.ToList())); 
      Data.Add(new Datum("g'bye, ", t2.ToList())); 
     } 
     public static List<Datum> Data = new List<Datum>(); 

     public Datum(string text, List<Triplet> combo) 
     { 
      this._text = text; 
      this._combo = combo.ToDictionary<Triplet,string>(o => o.KeyValue); 
      this.Current = combo[0].KeyValue; 
     } 

     private string _text; 
     public string Text 
     { 
      get 
      { 
       return _text; 
      } 
     } 

     private Dictionary<string, Triplet> _combo; 
     public List<Triplet> Combo 
     { 
      get 
      { 
       return _combo.Values.ToList(); 
      } 
     } 

     private string _result; 
     public string Result 
     { 
      get 
      { 
       return _result; 
      } 
     } 

     private string _current; 
     public string Current 
     { 
      get 
      { 
       return _current; 
      } 
      set 
      { 
       if (value != null && _combo.ContainsKey(value)) 
       { 
        _current = value; 
        _result = _combo[value].Description; 
       } 
      } 
     } 
    } 

    public class Triplet 
    { 
     public string KeyValue { get; set; } 
     public string KeyDisplayValue { get; set; } 
     public string Description { get; set; } 
     public Triplet(string keyValue, string keyDisplayValue, string description) 
     { 
      KeyValue = keyValue; 
      KeyDisplayValue = keyDisplayValue; 
      Description = description; 
     } 
    } 
} 
} 
0

आप CellValueChanged जो ग्रिड पर परिवर्तन ईवेंट सक्रिय और घटना के अंदर आप परिवर्तन हो और आदेश आइटम को बचाने के लिए नियंत्रण छोड़ने के बाद यह चयन किया जाता है चाहिए का उपयोग करना चाहिए।

private void FilterdataGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e) 
{ 
    FilterdataGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);  

    FilterdataGrid.EndEdit(DataGridViewDataErrorContexts.LeaveControl); 
} 

उम्मीद है कि यह मदद करता है!

+2

क्या आप अपने उत्तर में कुछ संदर्भ और स्पष्टीकरण जोड़ सकते हैं और भविष्य में उपयोगकर्ताओं से इसका लाभ उठा सकते हैं? सादा कोड के साथ उत्तर भविष्य के उपयोगकर्ताओं के लिए अधिक सामान्य उत्तर के रूप में सेवा करने की संभावना कम है। अधिक जानकारी के लिए [उत्तर] पर एक नज़र डालें। –

0

EndCurrentEdit के बारे में टिप के लिए ड्रोज के लिए धन्यवाद, जिसे मुझे इसे मेरे लिए काम करने की आवश्यकता थी। तो/नीचे तीर F4 का उपयोग कर, हर तीर क्लिक के परिणामस्वरूप -

private void dataGridViewEnumerable_CurrentCellDirtyStateChanged(object sender, EventArgs e) 
{ 
    var dataGridView = sender as DataGridView; 
    if (dataGridView == null || dataGridView.CurrentCell == null) 
    return; 
    var isComboBox = dataGridView.CurrentCell is DataGridViewComboBoxCell; 
    if ((isComboBox || dataGridView.CurrentCell is DataGridViewCheckBoxCell) 
    && dataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit) 
    && isComboBox && dataGridView.EndEdit()) 
    dataGridView.BindingContext[dataGridView.DataSource].EndCurrentEdit(); 
} 
2

इस समस्या के लिए CurrentCellDirtyStateChanged घटना तय माउस बातचीत, लेकिन यह कुंजीपटल बातचीत टूट जाता है: यह है कि मैं क्या तुरन्त DataGridViewComboBoxColumns और DataGridViewCheckBoxColumns प्रतिबद्ध करने के लिए कर रही है समाप्त हो गया है एक गंदे राज्य में परिवर्तन और संपादन करता है। मैंने जो समाधान पाया, वह "DataGridViewComboBoxEditingControl" को बनाए जाने पर पकड़ना था, और इसे ड्रॉपडाउन क्लोज़ड ईवेंट संलग्न करना था। यह कीबोर्ड और माउस इंटरैक्शन के लिए काम करता है। इस उदाहरण में, हमने डेटाग्रिड व्यू बढ़ाया है, इसलिए प्रत्येक इंस्टेंस इस कार्यक्षमता का उत्तराधिकारी होगा:

protected override void OnEditingControlShowing(DataGridViewEditingControlShowingEventArgs e) 
    { 
     DataGridViewComboBoxEditingControl control = e.Control as DataGridViewComboBoxEditingControl; 
     if (control != null) 
     { 
      control.DropDownClosed -= ComboBoxDropDownClosedEvent; 
      control.DropDownClosed += ComboBoxDropDownClosedEvent; 
     } 
     base.OnEditingControlShowing(e); 
    } 

    void ComboBoxDropDownClosedEvent(object sender, EventArgs e) 
    { 
     DataGridViewComboBoxCell cell = CurrentCell as DataGridViewComboBoxCell; 
     if ((cell != null) && cell.IsInEditMode) 
     { 
      CommitEdit(DataGridViewDataErrorContexts.Commit); 
      EndEdit(); 
     } 
    } 
संबंधित मुद्दे