WinForm में DataGridView को बाइंडिंग लिस्ट <T>


91

मुझे कक्षा में जाना है

class Person{
      public string Name {get; set;}
      public string Surname {get; set;}
}

और List<Person>जिसमें से मैं कुछ आइटम जोड़ता हूं। सूची मेरे लिए बाध्य है DataGridView

List<Person> persons = new List<Person>();
persons.Add(new Person(){Name="Joe", Surname="Black"});
persons.Add(new Person(){Name="Misha", Surname="Kozlov"});
myGrid.DataSource = persons;

कोई बात नहीं है। myGridदो पंक्तियों को प्रदर्शित करता है, लेकिन जब मैं अपनी personsसूची में नए आइटम जोड़ता हूं , myGridतो नई अद्यतन सूची नहीं दिखाता है। यह केवल उन दो पंक्तियों को दिखाता है जिन्हें मैंने पहले जोड़ा था।

तो समस्या क्या है?

हर बार रिबाइंड करना अच्छा काम करता है। लेकिन जब मैं DataTableग्रिड से बांधता हूं जब हर बार जब मैं DataTableवहां कुछ बदलाव करता हूं तो ReBind को कोई आवश्यकता नहीं होती है myGrid

हर बार बगावत किए बिना इसे कैसे हल किया जाए?

जवाबों:


187

सूची लागू नहीं होती है IBindingListइसलिए ग्रिड आपके नए आइटम के बारे में नहीं जानता है।

BindingList<T>इसके बजाय अपने DataGridView को बांधें ।

var list = new BindingList<Person>(persons);
myGrid.DataSource = list;

लेकिन मैं और भी आगे जाऊंगा और अपने ग्रिड को बांधूंगा BindingSource

var list = new List<Person>()
{
    new Person { Name = "Joe", },
    new Person { Name = "Misha", },
};
var bindingList = new BindingList<Person>(list);
var source = new BindingSource(bindingList, null);
grid.DataSource = source;

यह कहता है कि आप आइलिस्ट
Pacane

4
@Pacane: निश्चित रूप से आप कर सकते हैं, लेकिन DataGridView को यह जानने की आवश्यकता है कि क्या आपके डेटा स्रोत में कोई परिवर्तन है। Oneरास्ता एक बाइंडिंगलिस्ट का उपयोग करने के लिए है, जो अंतर्निहित सूची में परिवर्तन होने पर एक घटना को बढ़ाएगा। एक और तरीका है कि BindingSourceआप एक पंक्ति को जोड़ने / हटाने के लिए रीसेटबाइंडिंग () का उपयोग करें और अधिक काम करें। यदि आप संपत्ति के बारे में ग्रिड को सूचित करना चाहते हैं, तो सबसे आसान तरीका लागू करना हैINotifyPropertyChanged
Jürgen Steinblock

5
आपने BindingList और BindingSource का उपयोग क्यों किया क्योंकि हम सीधे डेटाग्रेडव्यू डेटा स्रोत संपत्ति के लिए सूची को बाँध सकते हैं। यहां उपयोग किए जाने वाले बाइंडलिस्ट और बाइंडिंगसोर्स यू के महत्व पर चर्चा करें। धन्यवाद
Mou

5
@ आप चाहें तो एक डेटाग्रिड को बाँध सकते List<T>हैं। लेकिन अगर आप प्रोग्राम में आइटम जोड़ते हैं तो लिस्ट डेटाग्रिड व्यू को इसके बारे में पता नहीं चलेगा क्योंकि आप लिस्ट का कोई मतलब नहीं है IBindingList। बाइंडिंग सोर्स के बारे में: मैं विनफॉर्म का बहुत उपयोग करता हूं, और मैं एक बाइंडिंगसोर्स - फुलस्टॉप के अलावा किसी और चीज से नहीं बांधता। अधिक विवरण जोड़ने के लिए एक टिप्पणी के लिए बहुत अधिक है, लेकिन BindingSourceबिना किसी नुकसान के प्रस्ताव के लिए बहुत कुछ है। मैं इतनी दूर जाऊंगा और कहूंगाAnyone who does not use a BindingSource for binding has not fully understood windows forms databindings
Jürgen Steinblock

4
@CraigBrett BindingSourceअपने डेटा स्रोत और अपने GUI के बीच एक सेतु के रूप में विचार करें । यह कई डेटाबाइंडिंग संबंधित समस्याओं को हल करता है। आप अपना डेटा पुनः लोड करना चाहते हैं? बस bindingSource.DataSourceहर नियंत्रण को रिबंड करने के बजाय अपने नए संग्रह पर सेट करें। आपका डेटा स्रोत अशक्त हो सकता है? सेट करें bindingSource.DataSource = typeof(YourClass)कि आप एक संपादन योग्य ग्रिड रखना चाहते हैं लेकिन आपके डेटा स्रोत में एक पैरामीटर रहित निर्माता नहीं है? बस bindingSource.AddingNewघटना को लागू करें और ऑब्जेक्ट स्वयं बनाएं। मैंने उपयोग करते समय कभी भी नकारात्मक पक्ष का अनुभव नहीं किया BindingSourceलेकिन बहुत सारे लाभ।
जुरगेन स्टीनब्लॉक

4

हर बार जब आप सूची में एक नया तत्व जोड़ते हैं तो आपको अपनी ग्रिड को फिर से बाँधने की आवश्यकता होती है। कुछ इस तरह:

List<Person> persons = new List<Person>();
persons.Add(new Person() { Name = "Joe", Surname = "Black" });
persons.Add(new Person() { Name = "Misha", Surname = "Kozlov" });
dataGridView1.DataSource = persons;

// added a new item
persons.Add(new Person() { Name = "John", Surname = "Doe" });
// bind to the updated source
dataGridView1.DataSource = persons;

मैं डेटा स्रोत को डेटाग्रिड के अंतर्गत नहीं देख सकता। क्या आप मुझे बता सकते हैं कि मैं इसका उपयोग कैसे करूँ?
RSB

2

हाँ, यह संभव है कि INotifyPropertyChanged इंटरफ़ेस को लागू करके रिबंडिंग के साथ किया जाए।

बहुत सरल उदाहरण यहाँ उपलब्ध है,

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx


1
यह पर्याप्त नहीं है, यदि आप कार्यान्वित INotifyPropertyChangedकरते हैं तो DataGridView पृष्ठभूमि में होने वाले सभी संपत्ति परिवर्तन दिखाएगा, लेकिन यह नहीं पता होगा कि क्या आप अपने स्रोत से एक पंक्ति जोड़ते / हटाते हैं। इस उद्देश्य के लिए एक IBindingListइंटरफ़ेस है और आपके BindingList<T>विश्वास के लिए , एक निहितार्थ जो पहले से ही इसे लागू करता है, लेकिन सॉर्टिंग या फ़िल्टरिंग का समर्थन नहीं करता है।
जर्गेन स्टीनब्लॉक

1
हां, मैं आपसे सहमत हूं। इसलिए मुझे लगता है कि इसके लिए ऑब्जर्वेबल कॉलेक्शन <T> का इस्तेमाल किया जा सकता है। तुम क्या सोचते हो?
देव

0

जोड़ने के लिए नया आइटम जोड़ने के बाद persons:

myGrid.DataSource = null;
myGrid.DataSource = persons;

मैं डेटा स्रोत को डेटाग्रिड के अंतर्गत नहीं देख सकता। क्या आप मुझे बता सकते हैं कि मैं इसका उपयोग कैसे करूँ?
RSB

1
यह सुझाव मुद्दों का कारण बन सकता है। उदाहरण के लिए, आप पा सकते हैं कि ग्रिड में किसी आइटम पर एक क्लिक से एक IndexOutOfRangeException मिल सकती है क्योंकि उस बिंदु पर डेटा स्रोत शून्य है। यह एक करने के लिए बाध्य करने के लिए समझदार होगा BindingList शुरू में और लागू INotifyPropertyChanged अपने वस्तु पर के रूप में अन्य उत्तर से संकेत मिलता है
स्टीव

nullयदि आप इसे तुरंत personsअगली पंक्ति में असाइन करते हैं, तो इसे निर्दिष्ट करने का क्या मतलब है ?
रुफस एल

0

यह वास्तव में मेरे पास का मुद्दा नहीं है, लेकिन अगर कोई भी किसी भी प्रकार के BindList को उसी प्रकार की सूची में बदलना चाहता है, तो यह है कि यह कैसे किया जाता है:

var list = bindingList.ToDynamicList();

इसके अलावा, यदि आप एक DataGridView.DataSource के लिए गतिशील प्रकारों के बाइंडिंगलिस्ट असाइन कर रहे हैं, तो सुनिश्चित करें कि आप इसे उपरोक्त कार्यों के रूप में पहले IBindingList घोषित करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.