2009-06-03 19 views
8

मेरे पास एक काफी बड़ी एएसपीनेट वेबसाइट है जो ग्रिड व्यू का उपयोग कई जगहों पर उसी ऑब्जेक्ट से बाध्य करती है। मैं प्रत्येक पंक्ति को अनुकूलित करने के लिए एक आइटम टेम्पलेट का उपयोग कर रहा हूँ। हालांकि सभी पृष्ठों में एक ही टेम्पलेट रखना है, मुझे & प्रतिलिपि बनाना है, प्रत्येक पृष्ठ पर आइटम टेम्पलेट पेस्ट करें। जाहिर है यह सबसे अच्छा समाधान नहीं है। इसके शीर्ष पर मैं कुछ कॉन्फ़िगरेशन फ़ाइल को बदलकर, GridView द्वारा उपयोग किए गए टेम्पलेट को बदलने में सक्षम होना चाहता हूं। एक विकल्प डेटाग्रिड के साथ उपयोगकर्ता नियंत्रण बनाना होगा और प्रत्येक पृष्ठ में उपयोग की जाने वाली आवश्यक गुणों का खुलासा करना होगा। हालांकि यह टेम्पलेट को गतिशील रूप से बदलने में सक्षम होने की दूसरी आवश्यकता को पूरा नहीं करता है। मूल रूप से मैं एक टेम्पलेट का उपयोग करने के लिए ग्रिड व्यू को कहने का तरीका ढूंढ रहा हूं और इसे गतिशील रूप से करने में सक्षम हूं। कोई विचार उपयोगी होगा।गतिशील रूप से ग्रिडव्यू आइटम टेम्पलेट को बदलें

+0

आप अलग अलग डिजाइन टेम्पलेट आप becoz टेम्पलेट बदलना चाहते हैं? –

+0

हां, मैं अलग-अलग डिज़ाइन टेम्पलेट्स रखना चाहता हूं और उन्हें गतिशील रूप से बदल सकता हूं – Albert

उत्तर

9

आदेश को पूरा करने के आप क्या चाहते हैं में, आपके पास दो विकल्प के रूप में मैं इसे देख:

1.) कोड में गतिशील रूप से प्रत्येक TemplateField निर्माण, और इन कुछ विन्यास के आधार पर स्विच करें।
2.) अपने कस्टम ग्रिड के लिए उपयोगकर्ता नियंत्रण बनाएं और इसके बजाय उन का उपयोग करें।

मुझे पता है कि आपने कहा है कि आप UserControl का उपयोग नहीं करना चाहते हैं क्योंकि इससे आपके लेआउट को गतिशील रूप से बदलने की आपकी क्षमता दूर हो जाएगी, लेकिन मुझे उदाहरण के साथ उस प्रीपोज़िशन को चुनौती देने दें।

PlaceHolder Control का उपयोग कर गतिशील रूप से उपयोगकर्ता नियंत्रण को अपनी पसंद के अनुसार स्विच करने के लिए आप अंतर्निहित एएसपी.Net सुविधाओं का उपयोग कर सकते हैं।

<asp:PlaceHolder ID="GridViewPlaceHolder" runat="server" /> 

आपका कस्टम ग्रिड तो जैसे .ascx फ़ाइलें में एलान के तौर पर बनाया जा सकता है और उसके बाद जगह में लोड गतिशील कार्यावधि में:

GridViewPlaceHolder.Controls.Add(LoadControl("~/Controls/MyCustomControl.ascx")); 

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

public abstract class CustomGridControl: System.Web.UI.UserControl 
{ 
    public abstract Object DataSource { get; set; } 
} 

एक साधारण ग्रिड मार्कअप में परिभाषित किया जा सकता:

<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="false"> 
    <Columns> 
     <asp:TemplateField HeaderText="Name"> 
      <ItemTemplate> 
       <asp:Label Text='<%#Eval("Name") %>' runat="server"></asp:Label> 
      </ItemTemplate> 
     </asp:TemplateField> 
     <asp:TemplateField HeaderText="Age"> 
      <ItemTemplate> 
       <asp:Label Text='<%#Eval("Age") %>' runat="server"></asp:Label> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

और उस पर नियंत्रण के लिए पीछे अपने कोड कुछ इस तरह दिखेगा:

public partial class SimpleGrid : CustomGridControl 
{ 
    public override object DataSource 
    { 
     get { return myGridView.DataSource; } 
     set { myGridView.DataSource = value; } 
    } 
} 

अब पेज या नियंत्रण का इस्तेमाल करता है इसे केवल बेस क्लास में डालना है, और आप इसे सामान्य रूप से उपयोग कर सकते हैं। निम्नलिखित का एक सरल उदाहरण है कि आप इसका उपयोग कैसे कर सकते हैं, लेकिन मुझे लगता है कि यह बिंदु स्पष्ट रूप से बनाता है:

protected void Page_Load(object sender, EventArgs e) 
{ 
    var dataSource = new List<MyCustomClass> 
         { 
          new MyCustomClass{Name = "Josh", Age = 43}, 
        new MyCustomClass{Name = "Bob", Age = 14}, 
        new MyCustomClass{Name = "Ashley", Age = 32}, 
         }; 

    DynamicallyLoadUserControlGrid("~/GridViewTemplates/SimpleGrid.ascx", dataSource); 
} 

private void DynamicallyLoadUserControlGrid(String controlLocation, List<MyCustomClass> dataSource) 
{ 
    var ctrl = (CustomGridControl)LoadControl(controlLocation); 
    ctrl.DataSource = dataSource; 
    ctrl.DataBind(); 

    GridViewPlaceHolder.Controls.Add(ctrl); 
} 

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

+0

आपको बहुत टैंक करना है, यह बिंदु समझने के बाद यह बहुत अच्छा काम करता है :) –

5

ठीक है, तो यहां 100% मैन्युअल रूप से टेम्पलेटेड फ़ील्ड उदाहरण का निर्माण कर रहा है।

गतिशील टेम्पलेट कॉलम बनाने में पहला कदम एक कक्षा बनाना है जो System.Web.UI.ITemplate इंटरफ़ेस लागू करता है। यहां हमारे सरल उदाहरण के लिए, मैं बस एक लेबल का उपयोग करने जा रहा हूं।

public class MyCustomTemplate : ITemplate 
{ 
    public String DataField { get; set; } 

    public MyCustomTemplate(String dataField) 
    { 
     DataField = dataField; 
    } 

    public void InstantiateIn(Control container) 
    { 
     var label = new Label(); 
     label.DataBinding += label_DataBinding; 

     container.Controls.Add(label); 
    } 

    void label_DataBinding(object sender, EventArgs e) 
    { 
     var label = (Label)sender; 
     var context = DataBinder.GetDataItem(label.NamingContainer); 
     label.Text = DataBinder.Eval(context, DataField).ToString(); 
    } 
} 

सूचना है कि आदेश DataBinding समर्थन करने के लिए, आप मैन्युअल जो कुछ भी नियंत्रण (रों) आप जोड़ने के लिए चुने पर उस घटना को संभालने के लिए होगा। एक बार जब आप अपना टेम्पलेट विकसित कर लेंगे, तो आप इसे किसी भी टेम्पलेटफ़ाइल के लिए अपने आइटम टेम्पलेट के रूप में उपयोग कर सकते हैं जिसका आप उपयोग करना चाहते हैं।

तो, मान लीजिए कि हमारे पास कस्टम व्यावसायिक वस्तुओं का कुछ संग्रह है जिसे हम अपने ग्रिड को बांधना चाहते हैं।

public class MyCustomClass 
{ 
    public String Name { get; set; } 
    public Int32 Age { get; set; } 
} 

हमें प्रत्येक कॉलम को टेम्पलेट फ़ील्ड के रूप में मैन्युअल रूप से बनाना होगा, और फिर हमारे संग्रह को ग्रिड व्यू में बांधना होगा।

public static class MyCustomTemplateCollection 
{ 
    public static DataControlFieldCollection GetTemplateCollection() 
    { 
     var col = new DataControlFieldCollection(); 

     var nameField = new TemplateField 
         { 
          HeaderText = "Name", 
          ItemTemplate = new MyCustomTemplate("Name") 
         }; 

     var ageField = new TemplateField 
         { 
          HeaderText = "Age", 
          ItemTemplate = new MyCustomTemplate("Age") 
         }; 

     col.Add(nameField); 
     col.Add(ageField); 

     return col; 
    } 
} 

अपने कोड में इस का उपयोग करते हुए पीछे कुछ इस तरह दिखेगा::

protected void Page_Load(object sender, EventArgs e) 
{ 
    var dataSource = new List<MyCustomClass> 
         { 
          new MyCustomClass{Name = "Josh", Age = 43}, 
        new MyCustomClass{Name = "Bob", Age = 14}, 
        new MyCustomClass{Name = "Ashley", Age = 32}, 
         }; 

    DynamicGrid(dataSource); 
} 

private void DynamicGrid(List<MyCustomClass> dataSource) 
{ 
    var col = MyCustomTemplateCollection.GetTemplateCollection(); 

    foreach (DataControlField field in col) 
    { 
     myGridView.Columns.Add(field); 
    } 

    myGridView.DataSource = dataSource; 
    myGridView.DataBind(); 
} 
आदेश में इस क्लीनर और ऐसा करने के लिए आसान बनाने के लिए में, मैं एक स्थिर सहायक वर्ग में TemplateField संग्रह के निर्माण समझाया है

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

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