2008-09-23 10 views
17

मैं निम्न वस्तु, कार, को ग्रिडव्यू में बाध्य करने के बारे में कैसे जाउंगा?क्या जटिल प्रकार के गुणों को एक डाटाग्रिड में बांधना संभव है?

 
public class Car 
{ 
    long Id {get; set;} 
    Manufacturer Maker {get; set;} 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 

आदिम प्रकार आसान बाध्य हो लेकिन मैं निर्माता के लिए कुछ भी प्रदर्शित करने का कोई तरीका मिल गया है। मैं निर्माता निर्माता को प्रदर्शित करना चाहता हूं। क्या यह भी संभव है?

ऐसा करने का कोई तरीका क्या होगा? क्या मुझे कार में निर्माता आईडी को स्टोर करना होगा और फिर निर्माता की सूची के साथ एक lookupEditRepository सेटअप करना होगा?

उत्तर

5
public class Manufacturer 
    { 
     long Id {get; set;} 
     String Name {get; set;} 

     public override string ToString() 
     { 
      return Name; 
     } 
    } 

स्ट्रिंग विधि को ओवरराइड करें।

+0

+1 मुझे लगता है कि यह सरल वस्तुओं के लिए एक ठोस समाधान है – karlipoppins

+0

यह सिर्फ एक संपत्ति चाहते हैं, लेकिन यह आपके साथ काम नहीं करेगा, उस वस्तु के गुणक गुण चाहते हैं। –

12

हां, आप घोंसले बाध्यकारी को पूरा करने के लिए टाइप डिस्क्रिप्शन प्रदाता बना सकते हैं।

http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx

+1

इसे प्राप्त करने के लिए जटिलता का स्तर बहुत अधिक है। क्या मेरे पास बाइंडेबल-क्लास का एक और सेट होना चाहिए जो मैं अपनी व्यावसायिक वस्तुओं को शायद बदल सकता हूं? – Xerx

+0

यह एक डिजाइन निर्णय है। या तो आपको केवल बाध्यकारी उद्देश्यों के लिए नई कक्षाओं का एक गुच्छा बनाना है या मेरी पोस्ट में दी गई नुस्खा का उपयोग करना है। व्यक्तिगत रूप से, मैं 'सहायक' के साथ अपने वर्ग पदानुक्रम को अपमानित करने से नफरत करता हूं, इसलिए मैं बाद वाले के साथ जाऊंगा। –

+0

+1 आलेख बिल्कुल वही है जो मुझे चाहिए ... – takrl

2

बस एक सूची का उपयोग करें और स्ट्रिंग "Maker.Name" करने के लिए DataMember सेट और अगर आप चाहते हैं DataKeyField कार के आईडी बस का उपयोग करने के: यहाँ एक MSDN ब्लॉग से एक विस्तृत उदाहरण है इसे "आईडी" पर सेट करें।

dataGrid.DataSource = carList; 
dataGrid.DataMember = "Maker.Name"; 
dataGrid.DataKeyField = "ID"; 
dataGrid.DataBind(); 

मुझे पता है कि पुनरावर्तक नियंत्रण में काम करता है, कम से कम ...

7

तरह से है कि मैं हाल ही में एक आवेदन में इस का दरवाजा खटखटाया मेरे अपने DataGridViewColumn और DataGridViewCell वर्गों में से एक के बंद इनहेरिट का निर्माण करना था मौजूदा डेटा जैसे DataGridViewTextBoxColumn और DataGridViewTextBoxCell।

आपके इच्छित सेल के प्रकार के आधार पर, आप बटन, चेकबॉक्स, कॉम्बोबॉक्स आदि जैसे अन्य लोगों का उपयोग कर सकते हैं। बस System.Windows.Forms में उपलब्ध प्रकारों पर नज़र डालें।

कोशिकाएं उनके मूल्य के साथ वस्तुओं के साथ सौदा करती हैं ताकि आप अपनी कार कक्षा को सेल के मूल्य में पारित कर सकें।

सेटवैल्यू और GetValue ओवरराइड करने से आपको मूल्य को संभालने के लिए आवश्यक अतिरिक्त तर्क प्राप्त करने की अनुमति मिल जाएगी।

उदाहरण के लिए:

public class CarCell : System.Windows.Forms.DataGridViewTextBoxCell 
{ 
    protected override object GetValue(int rowIndex) 
    { 
     Car car = base.GetValue(rowIndex) as Car; 
     if (car != null) 
     { 
      return car.Maker.Name; 
     } 
     else 
     { 
      return ""; 
     } 
    } 
} 

स्तंभ वर्ग मुख्य बात आप सब करने की ज़रूरत अपने कस्टम सेल वर्ग के लिए CellTemplate सेट किया गया है पर।

public class CarColumn : System.Windows.Forms.DataGridViewTextBoxColumn 
{ 
    public CarColumn(): base() 
    { 
     CarCell c = new CarCell(); 
     base.CellTemplate = c; 
    } 
} 

इन कस्टम कॉलम का उपयोग करके/DataGridView पर कोशिकाओं यह है कि आप अपने DataGridView करने के लिए अतिरिक्त कार्यक्षमता का एक बहुत जोड़ने के लिए अनुमति देता है।

मैंने उन्हें स्ट्रिंग मानों पर कस्टम स्वरूपण लागू करने के लिए GetFormattedValue को ओवरराइड करके प्रदर्शित स्वरूपण को बदलने के लिए उपयोग किया।

मैंने पेंट पर ओवरराइड भी किया ताकि मैं मूल्य परिस्थितियों के आधार पर कस्टम सेल हाइलाइटिंग कर सकूं, सेल स्टाइल को बदलना। बैककोलर जो मैं मूल्य के आधार पर चाहता था।

2

यदि आप बाध्यकारी लक्ष्यों के रूप में विशिष्ट, नेस्टेड गुणों का खुलासा करना चाहते हैं, तो बेन हॉफस्टीन का उत्तर (http://blogs.msdn.com/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx) बहुत अच्छा है। संदर्भित लेख थोड़ा उलझन में है, लेकिन यह काम करता है।

यदि आप सिर्फ एक जटिल संपत्ति (उदा। निर्माता) के लिए एक कॉलम बांधना चाहते हैं और प्रतिपादन तर्क को ओवरराइड करना चाहते हैं, तो या तो मैनियाएक्सएक्स की सिफारिश की जाती है, या बस बाउंडफ़ील्ड को उपclass और FormatDataValue() का एक कस्टम कार्यान्वयन प्रदान करें। यह ToString() को ओवरराइड करने के समान है; आपको ऑब्जेक्ट संदर्भ मिलता है, और आप अपनी ग्रिड में प्रदर्शित स्ट्रिंग को वापस कर देते हैं।

कुछ इस तरह:

public class ManufacturerField : BoundField 
{ 
    protected override string FormatDataValue(object dataValue, bool encode) 
    { 
     var mfr = dataValue as Manufacturer; 

     if (mfr != null) 
     { 
      return mfr.Name + " (ID " + mfr.Id + ")"; 
     } 
     else 
     { 
      return base.FormatDataValue(dataValue, encode); 
     } 
    } 
} 

बस अपने ग्रिड से एक ManufacturerField जोड़ने को निर्दिष्ट डेटा फ़ील्ड के रूप में "निर्माता", और आप के लिए तैयार हैं।

+0

+1 लिंक किया गया लेख बिल्कुल वही है जो मुझे चाहिए था। – takrl

1

मैं यह मान लेगा कि निम्न कर सकता है:

public class Car 
{ 
    public long Id {get; set;} 
    public Manufacturer Maker {private get; set;} 

    public string ManufacturerName 
    { 
     get { return Maker != null ? Maker.Name : ""; } 
    } 
} 

public class Manufacturer 
{ 
    long Id {get; set;} 
    String Name {get; set;} 
} 
+1

वास्तव में लोग वास्तव में क्या करना चाहते हैं लेकिन यह डेमेटर के कानून के साथ अधिक उत्साहित प्रतीत होता है। – jpierson

2

यहाँ एक और विकल्प मैं काम कर गया है:

<asp:TemplateColumn 
    HeaderText="Maker"> 
    <ItemTemplate> 
      <%#Eval("Maker.Name")%> 
    </ItemTemplate> 
</asp:TemplateColumn> 

ASP.NET 4.0 में हो सकती है लेकिन यह एक आकर्षण की तरह काम करता है!

22

ठीक है दोस्तों ... इस सवाल को वापस पोस्ट किया गया था, लेकिन मुझे नेस्टेड गुणों को पुनर्प्राप्त करने के लिए सेल_फॉर्मेटिंग ईवेंट में प्रतिबिंब का उपयोग करके ऐसा करने के लिए काफी अच्छा & सरल तरीका मिला।

इस प्रकार है:

private void Grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
    { 

     DataGridView grid = (DataGridView)sender; 
     DataGridViewRow row = grid.Rows[e.RowIndex]; 
     DataGridViewColumn col = grid.Columns[e.ColumnIndex]; 
     if (row.DataBoundItem != null && col.DataPropertyName.Contains(".")) 
     { 
      string[] props = col.DataPropertyName.Split('.'); 
      PropertyInfo propInfo = row.DataBoundItem.GetType().GetProperty(props[0]); 
      object val = propInfo.GetValue(row.DataBoundItem, null); 
      for (int i = 1; i < props.Length; i++) 
      { 
       propInfo = val.GetType().GetProperty(props[i]); 
       val = propInfo.GetValue(val, null); 
      } 
      e.Value = val; 
     } 
    } 

और बस हो गया! अब आप अपने कॉलम के लिए DataPropertyName में परिचित वाक्यविन्यास "ParentProp.ChildProp.GrandChildProp" का उपयोग कर सकते हैं।

+0

महान काम किया! साझा करने के लिए धन्यवाद। – Amir

+0

बहुत अच्छा, धन्यवाद ^^ – Mahmoud

+0

यह अधिक अपवर्तनीय है! पता नहीं क्या हो रहा है लेकिन यह काम करता है। साझा करने के लिए धन्यवाद!!! –

संबंधित मुद्दे