ये बहुत गन्दा हैं।
यहां एक बहुत ही सरल और सुरुचिपूर्ण समाधान है। कहें कि आपकी ग्रिड को 3 कॉलम वाले टेबल में डेटा प्रदर्शित करने की आवश्यकता है। डेटा निम्नलिखित संरचना के साथ एक वस्तु से आ रही है:
मार्कअप (GridDisplayRow.ascx):
[Serializable]
public class Foo
{
public string Bar1 { get; set; }
public string Bar2 { get; set; }
public string Bar3 { get; set; }
}
फिर अपने उपयोगकर्ता नियंत्रण निम्न मार्कअप होगा
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="GridDisplayRow.ascx.cs" Inherits="GridDisplayRow" %>
<div>
<div class="cell">
<asp:TextBox id="TxtProperty1" runat="server"/>
</div>
<div class="cell">
<asp:DropDownList ID="DDLProperty2" runat="server" OnSelectedIndexChanged="DDLProperty2_OnSelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList>
</div>
<div class="cell">
<input type="radio" id="RadProperty3" runat="server">
</div>
</div>
सूचना सभी div टैग बच्चों के div तैर रहे हैं ... ताकि वे एक तरफ प्रदर्शित करते हैं।
codebehind (GridDisplayRow.ascx.cs):
class GridDisplayRow:UserControl
{
public event EventHandler<System.EventArgs> SomethingHappened;
protected void Page_Load(object sender, EventArgs e)
{
//Initialize the drop down with something;
}
//this is where we handle internal events generated by children controls.
//Eg: the drop down's index changed.
protected void DDLProperty2_OnSelectedIndexChanged(object sender, EventArgs e)
{
//we update some other child control in this...
this.TxtProperty1.Text = this.DDLProperty2.Value;
//and maybe we want to signal the page that some event happened
if(SomethingHappened != null)
{
//Notify the page that SomethingHappened event occured
SomethingHappened(this, EventArgs.Empty);
}
}
//This is where the binding happens
public object BindingObject
{
set
{
Foo temp = (Foo)value;
this.TxtProperty1.Text = temp.Bar1;
this.DDLProperty2.Value = temp.Bar2;
this.RadProperty3.Value = temp.Bar3;
this.ViewState["Foo"] = temp;
}
}
}
तो कोड ऊपर हम संभाल रहे हैं में फू के लिए बाध्य, दूसरे शब्दों में हम प्रत्येक कोशिका में फू के गुण प्रदर्शित कर रहे हैं (div) नियंत्रण से ।कास्ट की आवश्यकता है क्योंकि ऊपर की संपत्ति प्रकार की वस्तु है, और ग्रिड/रिपेटर के आइटम टेम्पलेट में/आप क्या हैं, आप GridDisplayRow के कंटेनर। डेटाटाइम ऑब्जेक्ट के उदाहरण को बाध्य दिखाएंगे।
पृष्ठ मार्कअप::
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>
<%@ Register src="GridDisplayRow.ascx" tagname="GridRow" tagprefix="ctrl" %>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<div>
<div class="header cell">Header 1</div>
<div class="header cell">Header 2</div>
<div class="header cell">Header 3</div>
</div>
</HeaderTemplate>
<ItemTemplate>
<ctrl:GridRow ID="Row" runat="server" BindingObject='<%# Container.DataItem %>' OnSomethingHappened="Row_SomethingHappened" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
मैं काम कर रहा पसंद नहीं है बस यह है कि यदि आपके डेटा स्रोत उदाहरण के लिए एक डेटासेट है, तो आप DataRow को कास्ट करने के लिए है, या जो कुछ भी उचित डेटा प्रकार की जरूरत है को ध्यान में रखना ग्रिड के साथ क्योंकि वे गन्दा और बोझिल हैं। इस उदाहरण में हमने प्रति पंक्ति एक सेल के साथ एक टेबल बनाने के लिए ग्रिड को धोखा दिया, और स्टाइल शीट के माध्यम से उस सेल के लेआउट का ख्याल रखा।
कृपया ध्यान दें कि यह एक पुनरावर्तक के साथ बेहतर काम करता है क्योंकि यह सुपर कुशल है और इसमें कम ओवरहेड है!
अब ग्रिड को बाध्यकारी: किसी भी स्रोत जो IENumerable लागू करता है, को ग्रिड से बांधने के लिए उपयोग किया जा सकता है। चूंकि सूची जैसे संग्रह पर्याप्त होंगे।
जब ग्रिडरो नियंत्रण अपनी घटनाओं को सक्रिय करता है, तो नियंत्रण का संदर्भ ऑब्जेक्ट प्रेषक के माध्यम से भेजा जाता है, इस प्रकार यदि आप प्रेषक को अपने सही प्रकार पर डालते हैं तो आप नियंत्रण के आंतरिक गुणों को पकड़ सकते हैं .... संभावनाएं अनंत हैं।
ऐसी विधि का लाभ अमूर्त है। प्रत्येक नियंत्रण अपनी घटनाओं को संभाल सकता है, या इसके अंदर होने वाली घटनाओं के पृष्ठ को सूचित करने के लिए चुना है .... bla bla bla। तुम्हें नया तरीका मिल गया है।