2008-10-24 12 views
15

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

मेरे पास मेरे मार्कअप - कॉलम 0, टेम्पलेट कॉलम में केवल एक कॉलम परिभाषित किया गया है, जिसमें मैं एक चयन लिंक और अन्य एप्लिकेशन विशिष्ट लिंकबटन घोषित करता हूं। उस कॉलम को हमेशा वहां रहने की जरूरत है। जब ListBoxSelection बनाया जाता है, तो मैं पहले कॉलम के अलावा सभी को हटा देता हूं और फिर वांछित कॉलम को दोबारा जोड़ता हूं (इस नमूने में, मैंने हमेशा इसे "शीर्षक" कॉलम जोड़ने के लिए सरल बना दिया है)। यहाँ कोड का एक हिस्सा है:

RemoveVariableColumnsFromGrid(); 
BoundField b = new BoundField(); 
b.DataField = "Title"; 
this.gvPrimaryListView.Columns.Add(b); 
this.gvPrimaryListView.DataBind(); 


private void RemoveVariableColumnsFromGrid() { 
    int ColCount = this.gvPrimaryListView.Columns.Count; 
    //Leave column 0 -- our select and view template column 
    while (ColCount > 1) { 
     this.gvPrimaryListView.Columns.RemoveAt(ColCount - 1); 
     --ColCount; 
    } 
} 

पहली बार इस कोड के माध्यम से चलाता है, मैं दोनों स्थिर स्तंभ और गतिशील रूप से जोड़ा "शीर्षक" कॉलम देखें। हालांकि, अगली बार चयन किया जाता है, पहला कॉलम खाली होता है (इसमें कुछ भी नहीं)। मुझे शीर्षक कॉलम दिखाई देता है, और मैं इसके बाईं ओर पहला कॉलम देखता हूं - लेकिन इसमें कुछ भी उत्पन्न नहीं होता है। डीबगर में, मैं देख सकता हूं कि gvPrimaryListView में वास्तव में अभी भी दो कॉलम हैं और पहला (इंडेक्स 0) वास्तव में एक टेम्पलेट कॉलम है। वास्तव में, कॉलम भी इसकी चौड़ाई को बरकरार रखता है जो नीचे दिए गए मार्कअप में 165 पीएक्स के रूप में सेट किया गया है (डीबगिंग उद्देश्यों के लिए)।

कोई विचार?

<asp:GridView ID="gvPrimaryListView" runat="server" Width="100%" AutoGenerateColumns="false" 
    DataKeyNames="Document_ID" EnableViewState="true" DataSourceID="odsPrimaryDataSource" 
    AllowPaging="true" AllowSorting="true" PageSize="10" OnPageIndexChanging="activeListView_PageIndexChanging" 
    AutoGenerateSelectButton="False" OnSelectedIndexChanged="activeListView_SelectedIndexChanged" 
    Visible="true" OnRowDataBound="CtlDocList_RowDataBound" Font-Size="8pt" Font-Names="Helvetica"> 
    <Columns> 
     <asp:TemplateField ShowHeader="false"> 
      <ItemTemplate> 
       <asp:LinkButton EnableTheming="false" ID="CtlSelectDocRowBtn" runat="server" Text="Select" 
        CommandName="Select" CssClass="gridbutton" OnClick="RowSelectBtn_Click" /> 
       <asp:ImageButton EnableTheming="false" ID="DocViewBtn" runat="server" ImageUrl="../../images/ViewDoc3.png" 
        CssClass="gridbutton" CommandName="Select" OnClick="DocViewBtn_Click" /> 
      </ItemTemplate> 
      <ItemStyle Width="165px" /> 
     </asp:TemplateField> 
    </Columns> 
    <EmptyDataTemplate> 
     <asp:Label ID="Label6" runat="server" Text="No rows found." SkinID="LabelHeader"></asp:Label> 
    </EmptyDataTemplate> 
</asp:GridView> 

बस कुछ अतिरिक्त जानकारी।

इस तथ्य से कोई लेना-देना नहीं है कि यह पहला कॉलम है लेकिन इस तथ्य के साथ सबकुछ करना है कि यह एक टेम्पलेटफिल्ड है। अगर मैं बाईं ओर एक सामान्य कॉलम डालता हूं (मार्कअप में) और टेम्पलेटफ़िल्ल्ड कॉलम को दाईं ओर स्थानांतरित करता हूं, तो पहला कॉलम ठीक से प्रस्तुत करता है, और (अब दूसरा) टेम्पलेटफ़िल्ल्ड कॉलम गायब हो जाता है।

एक और अजीब बात - समस्या पहली पोस्टबैक नहीं होती है - या दूसरा - लेकिन यह तीसरे पोस्टबैक पर शुरू होता है और फिर बाद के पोस्टबैक के लिए जारी रहता है। मैं उलझन में हूं।

+0

मैं एक ही कर रहा हूँ गतिशील कोड में कॉलम जोड़ने का तरीका पीछे, हालांकि, समस्या यह है कि यदि मैं 20+ कॉलम गतिशील रूप से जोड़ता हूं, तो प्रत्येक लूप पूरे पृष्ठ को धीमा कर देता है, क्या आपके पास एक ही समस्या है? – Princa

उत्तर

0

मुझे डेटाकंट्रोलफ़िल्ल्डकोलेक्शन क्लास के तहत, दस्तावेज़ में यह छोटा नगेट मिला।

आप (उदाहरण के लिए जब AutoGenerateColumns संपत्ति सच है) GridView या DetailsView नियंत्रण, DataControlField वस्तुओं कि स्वचालित रूप से बनाई गई हैं उपयोग कर रहे हैं सार्वजनिक रूप से सुलभ क्षेत्रों संग्रह में संग्रहीत नहीं हैं। आप केवल DataControlField ऑब्जेक्ट्स को एक्सेस और हेरफेर कर सकते हैं जो स्वचालित रूप से जेनरेट नहीं होते हैं।

मुझे लगता है कि उत्तर कोड में आपके सभी कॉलम हेरफेर करना है, और फिर आपके दृष्टिकोण को ठीक काम करना चाहिए।

0

गतिशील रूप से कॉलम जोड़ने के बजाय, क्या आप उन्हें शुरुआत में परिभाषित कर सकते हैं और उन्हें आवश्यकतानुसार छुपा सकते हैं (या तो दृश्यमान = "झूठी" के साथ या नियंत्रण/हेडर/पाद लेख के सीएसएस क्लास को "डिस्प्ले" कोई नहीं; ")? मैं इस विधि का उपयोग अपने कुछ कोड में टेम्पलेट कॉलम सहित, बिना किसी समस्या के करता हूं।

0

क्षमा करें, डेकर। मैं स्पष्ट रूप से कुछ महत्वपूर्ण बिंदुओं को याद किया .. :)

यदि यह अभी भी आपके लिए एक समस्या है, तो मुझे आश्चर्य है कि इससे आपके आइटम टेम्पलेट में क्या अंतर होता है? यदि आप वहां कुछ टेक्स्ट डालते हैं, तो पेज को कुछ बार रीफ्रेश करें, क्या टेक्स्ट पहले लोड पर दिखाई देता है, फिर दूसरे पर नहीं?

साथ ही, जब समस्या उत्पन्न होती है तो क्या कोशिकाओं में कोई HTML मार्कअप होता है या वे पूरी तरह खाली होते हैं?

5

मैंने हाल ही में ग्रिडव्यू में गतिशील कॉलम के साथ silmilar मुद्दों पर विजय प्राप्त की, शायद यह मदद करेगा।

पहले एक समारोह oninit घटना
अन्त में मैं निम्नलिखित सहायक वर्ग इस्तेमाल किया चेक बॉक्स का दृष्टांत के लिए जब RowDataBound घटना शुरू हुआ पैदा करने के लिए में निकाल दिया में प्रोग्राम के स्तंभ जोड़ने बंद
दूसरा viewstate बदल जाते हैं। हां इसमें से कुछ मुश्किल कोडित है।

हेक यहां सभी कोड है। इस पर है :) वारंटी जैसा है, ब्ला ब्ला ब्ला ...

आखिरकार जब से मैं अपने पैरों को गीला कर रहा हूं डॉटनेट किसी भी सुझाव की सराहना की जाएगी [आईई मुझे बहुत ज्यादा चीर नहीं है :)]। और हाँ 'उधार' प्रारंभिक वेब से कहीं कोड, खेद मैं अपने सिर :(

के ऊपर से याद नहीं कर सकते - बंद संरक्षित ओवरराइड शून्य में आग इस OnInit

private void GridViewProject_AddColumns() 
    { 
     DataSet dsDataSet = new DataSet(); 
     TemplateField templateField = null; 

     try 
     { 
      StoredProcedure sp = new StoredProcedure("ExpenseReportItemType_GetList", "INTRANETWEBDB", Context.User.Identity.Name); 
      dsDataSet = sp.GetDataSet(); 

      if (sp.RC != 0 && sp.RC != 3000) 
      { 
       labelMessage.Text = sp.ErrorMessage; 
      } 

      int iIndex = 0; 
      int iCount = dsDataSet.Tables[0].Rows.Count; 
      string strCategoryID = ""; 
      string strCategoryName = ""; 
      iStaticColumnCount = GridViewProject.Columns.Count; 

      // Insert all columns immediatly to the left of the LAST column 
      while (iIndex < iCount) 
      { 
       strCategoryName = dsDataSet.Tables[0].Rows[iIndex]["CategoryName"].ToString(); 
       strCategoryID = dsDataSet.Tables[0].Rows[iIndex]["CategoryID"].ToString(); 

       templateField = new TemplateField(); 
       templateField.HeaderTemplate = new GridViewTemplateExternal(DataControlRowType.Header, strCategoryName, strCategoryID); 
       templateField.ItemTemplate = new GridViewTemplateExternal(DataControlRowType.DataRow, strCategoryName, strCategoryID); 
       templateField.FooterTemplate = new GridViewTemplateExternal(DataControlRowType.Footer, strCategoryName, strCategoryID); 

       // Have to decriment iStaticColumnCount to insert dynamic columns BEFORE the edit row 
       GridViewProject.Columns.Insert((iIndex + (iStaticColumnCount-1)), templateField); 
       iIndex++; 
      } 
      iFinalColumnCount = GridViewProject.Columns.Count; 
      iERPEditColumnIndex = (iFinalColumnCount - 1); // iIndex is zero based, Count is not 
     } 
     catch (Exception exception) 
     { 
      labelMessage.Text = exception.Message; 
     } 
    } 

- हेल्पर क्लास

public class GridViewTemplateExternal : System.Web.UI.ITemplate 
{ 
    #region Fields 
    public DataControlRowType DataRowType; 
    private string strCategoryID; 
    private string strColumnName; 
    #endregion 

    #region Constructor 
    public GridViewTemplateExternal(DataControlRowType type, string ColumnName, string CategoryID) 
    { 
     DataRowType = type; // Header, DataRow, 
     strColumnName = ColumnName; // Header name 
     strCategoryID = CategoryID; 
    } 
    #endregion 

    #region Methods 
    public void InstantiateIn(System.Web.UI.Control container) 
    { 
     switch (DataRowType) 
     { 
      case DataControlRowType.Header: 
       // build the header for this column 
       Label labelHeader = new Label(); 
       labelHeader.Text = "<b>" + strColumnName + "</b>"; 
       // All CheckBoxes "Look Up" to the header row for this information 
       labelHeader.Attributes["ERICategoryID"] = strCategoryID; 
       labelHeader.Style["writing-mode"] = "tb-rl"; 
       labelHeader.Style["filter"] = "flipv fliph"; 
       container.Controls.Add(labelHeader); 
       break; 
      case DataControlRowType.DataRow: 
       CheckBox checkboxAllowedRow = new CheckBox(); 
       checkboxAllowedRow.Enabled = false; 
       checkboxAllowedRow.DataBinding += new EventHandler(this.CheckBox_DataBinding); 
       container.Controls.Add(checkboxAllowedRow); 
       break; 
      case DataControlRowType.Footer: 
       // No data handling for the footer addition row 
       CheckBox checkboxAllowedFooter = new CheckBox(); 
       container.Controls.Add(checkboxAllowedFooter); 
       break; 
      default: 
       break; 
     } 
    } 
    public void CheckBox_DataBinding(Object sender, EventArgs e) 
    { 
     CheckBox checkboxAllowed = (CheckBox)sender;// get the control that raised this event 
     GridViewRow row = (GridViewRow)checkboxAllowed.NamingContainer;// get the containing row 
     string RawValue = DataBinder.Eval(row.DataItem, strColumnName).ToString(); 
     if (RawValue.ToUpper() == "TRUE") 
     { 
      checkboxAllowed.Checked = true; 
     } 
     else 
     { 
      checkboxAllowed.Checked = false; 
     } 
    } 
    #endregion 
} 
1

diningphilanderer.myopenid.com मैं क्या सिफारिश करेंगे करने के लिए एक समान दृष्टिकोण है।

समस्या आप ग्रिड हर बार एक पोस्टबैक rebind करना है होता है और इसके परिणामस्वरूप आपको कॉलम का पुनर्निर्माण करना होता है। मुझे बाइंडग्रिड() नामक एक विधि पसंद है जो पहले कॉलम ग्रिड व्यू 1 को साफ़ करता है। कॉलम। क्लीयर(); फिर उन्हें प्रोग्रामिक रूप से जोड़ता है, फिर डेटास्रोत सेट करता है और डेटाबेस कॉल करता है। सुनिश्चित करें कि आपके पास ग्रिड के लिए व्यूस्टेट अक्षम है और आपके पास autogeneratecolumns = false है;

1

मुझे यह पहले आज मिला: TemplateField in a GridView doesn't have its ViewState restored when BoundFields are inserted

ऐसा लगता है कि माइक्रोसॉफ्ट फिक्सिंग पर योजना नहीं बना रहा है, इसलिए आपको ऊपर दिए गए समाधानों में से एक को आजमा देना होगा। मुझे एक ही समस्या है - मेरे पास कुछ डेटाबाउंडफिल्ड्स और कुछ टेम्पलेटफिल्ड्स हैं, और पोस्टबैक के बाद, टेम्पलेटफ़ील्ड आधारित कॉलम उनके नियंत्रण और डेटा खो देते हैं।

1

मैंने उसी विषय पर एक संक्षिप्त लेख लिखा है जो उपयोगकर्ता द्वारा चेकबॉक्स लिंक नियंत्रण में चयनित कॉलम के आधार पर गतिशील रूप से पॉप्युलेटिंग ग्रिड व्यू कॉलम से निपटता है। उम्मीद है कि इससे सरल प्रदर्शन How to generate GridView columns dynamically based on user selection? की तलाश करने वालों की मदद मिलेगी।

1
void Page_PreRenderComplete(object sender, EventArgs e) 
    { 
     // TemplateField reorder bug: if there is a TemplateField based column (or derived therefrom), GridView may blank out 
     // the column (plus possibly others) during any postback, if the user has moved it from its original markup position. 
     // This is probably a viewstate bug, as it happens only if a TemplateField based column has been moved. The workaround is 
     // to force a databind before each response. See https://connect.microsoft.com/VisualStudio/feedback/details/104994/templatefield-in-a-gridview-doesnt-have-its-viewstate-restored-when-boundfields-are-inserted 
     // 
     // This problem is also happening for grid views inside a TabPanel, even if the TemplateField based columns have not 
     // been moved. Also do a databind in that case. 
     // 
     // We also force a databind right after the user has submitted the column chooser dialog. 
     // (This is because the user could have moved TemplateField based column(s) but ColChooserHasMovedTemplateFields() 
     // returns false -- ie when the user has moved all TemplateField based columns back to their original positions. 
     if ((!_DataBindingDone && (ColChooserHasMovedTemplateFields() || _InTabPanel)) || _ColChooserPanelSubmitted || _ColChooserPanelCancelled) 
      DataBind(); 

     // There is a problem with the GridView in case of custom paging (which is true here) that if we are on the last page, 
     // and we delete all row(s) of that page, GridView is not aware of the deletion during the subsequent data binding, 
     // will ask the ODS for the last page of data, and will display a blank. By PreRenderComplete, it will somehow have 
     // realized that its PageIndex, PageCount, etc. are too big and updated them properly, but this is too late 
     // as the data binding has already occurred with oudated page variables. So, if we were on the last page just before 
     // the last data binding (_LastPageIndex == _LastPageCount - 1) and PageIndex was decremented after the data binding, 
     // we know this scenario has happened and we redo the data binding. See http://scottonwriting.net/sowblog/archive/2006/05/30/163173.aspx 
     // for a discussion of the problem when the GridView uses the ODS to delete data. The discussion also applies when we 
     // delete data directly through ClassBuilder objects. 
     if (_LastPageIndex == _LastPageCount - 1 && PageIndex < _LastPageIndex) 
      DataBind(); 

     if (EnableColChooser) 
     { 
      if (!_IsColChooserApplied) 
       ApplyColChooser(null, false, false); 
      else 
      { 
       // The purpose of calling ApplyColChooser() here is to order the column headers properly. The GridView 
       // at this point will have reverted the column headers to their original order regardless of ViewState, 
       // so we need to apply our own ordering. (This is not true of data cells, so we don't have to apply 
       // ordering to them, as reflected by the parameters of the call.) 

       // If we have already processed column reordering upon the column chooser panel being submitted, 
       // don't repeat the operation. 
       if (!_ColChooserPanelSubmitted) 
        ApplyColChooser(null, false, true); 
      } 
     } 
    } 
संबंधित मुद्दे