locked
How to set CSS class on ITemplate column RRS feed

  • Question

  • User-2024822571 posted

    Hello,

    I'm working with a GridView and am dynamically adding columns to it based on my own class which implements the ITemplate class.

    As part of my new columns I would like to set the class for one of the tags dynamically on data bind but the following code simply shows my function as the class:

    public class ForecastDayColumn : ITemplate
    { private DataControlRowType m_templateType; private DateTime m_columnName; private Double m_colNumber; private Boolean m_showDetails; public ForecastDayColumn(DataControlRowType type, Int32 colDay, DateTime colName, Boolean showDetails)
    { m_templateType = type; m_colNumber = colDay; m_columnName = colName; m_showDetails = showDetails; } public void InstantiateIn(System.Web.UI.Control container)
    { // Create the content for the different row types. switch (m_templateType)
    { case DataControlRowType.Header: Literal dayLiteral = new Literal(); dayLiteral.Text = m_columnName.Day.ToString(); container.Controls.Add(dayLiteral); break; case DataControlRowType.DataRow: Label balance = new Label(); HyperLink salesLink = new HyperLink(); HyperLink receiptLink = new HyperLink(); balance.DataBinding += new EventHandler(this.Balance_DataBinding); salesLink.DataBinding += new EventHandler(this.SalesLink_DataBinding); receiptLink.DataBinding += new EventHandler(this.ReceiptLink_DataBinding); Literal startSummary = new Literal();
    // This next line is where I think I should be setting the css-class function
    startSummary.Text = "<div id=\"summary" + m_colNumber + "\" align=\"right\" class=\"<%# FormatMovementField(1) %>\">"; Literal startDetail = new Literal(); startDetail.Text = "<div id=\"detail" + m_colNumber + "\" align=\"right\">"; Literal br = new Literal(); br.Text = "<br />"; Literal endDiv = new Literal(); endDiv.Text = "</div>"; container.Controls.Add(startSummary); container.Controls.Add(balance); if (m_showDetails)
    { container.Controls.Add(startDetail); container.Controls.Add(salesLink); container.Controls.Add(br); container.Controls.Add(receiptLink); container.Controls.Add(endDiv); } container.Controls.Add(endDiv); break; default: // Insert code to handle unexpected values.
    break;
    }
    }
    private void Balance_DataBinding(Object sender, EventArgs e)
    { Label balanceLabel = (Label)sender; GridViewRow row = (GridViewRow)balanceLabel.NamingContainer; Object dataValue = DataBinder.Eval(row.DataItem, "DailyForecastData[" + m_colNumber + "].Balance"); if (dataValue != DBNull.Value)
    { balanceLabel.Text = dataValue.ToString(); } }
    private void SalesLink_DataBinding(Object sender, EventArgs e)
    { HyperLink salesHyperLink = (HyperLink)sender; GridViewRow row = (GridViewRow)salesHyperLink.NamingContainer; Object dataValue = DataBinder.Eval(row.DataItem, "DailyForecastData[" + m_colNumber + "].SalesQty"); if (dataValue != DBNull.Value)
    { if (dataValue.ToString() == "0")
    { salesHyperLink.Text = dataValue.ToString(); } else
    { salesHyperLink.Text = "-" + dataValue.ToString(); } salesHyperLink.ID = "demand" + m_colNumber.ToString(); } }
    private void ReceiptLink_DataBinding(Object sender, EventArgs e)
    { HyperLink receiptHylerLink = (HyperLink)sender; GridViewRow row = (GridViewRow)receiptHylerLink.NamingContainer; Object dataValue = DataBinder.Eval(row.DataItem, "DailyForecastData[" + m_colNumber + "].ReceiptQty"); if (dataValue != DBNull.Value)
    { receiptHylerLink.Text = dataValue.ToString(); receiptHylerLink.ID = "receipts" + m_colNumber.ToString(); } } }

    So when I run the page i see the aspx as:

    <div id="summary0" align="right" class="<%# FormatMovementField(1) %>">

    Any ideas on if this is the correct way to do this and if so how do I get it to work? If not then how should I set the css class for a dynamic template column control to be a function?

    Mike

    Monday, December 12, 2011 7:22 AM

All replies

  • User3866881 posted

    startSummary.Text = "<div id=\"summary" + m_colNumber + "\" align=\"right\" class=\"<%# FormatMovementField%>

    Hello:)

    Why do you use “<%# FormatMovementField%>” here?This will cause a problem of directly outputting a plain string instead of doing a data binding here……

    Solution:

    Either open a public property for users to set a CSS name or just directly use a fixed CSS name instead of using "<%# FormatMovementField%>"。

    Best reguards!

    Tuesday, December 13, 2011 9:15 PM
  • User-2024822571 posted
    Decker, The aim of using the "<%# FormatMovementField%>" was to enable the class to be derrived at binding time. I would like to display one CSS Class if the bound value meets some requirements and another if it does not. That logic is (will be) contained in the FormatMovementField() method. I thought I had seen some examples where the stylecould be dynamically selected at binding time, but my implementation for a dynamic column dosn't seem to be working. I am unable to directly bind a fixed CSS name at the time of generating the column as the value for the field is not known at that time. I'm interested in the public property option of which you speak as I'm not familiar with that technique. Can you elaborate? Mike
    Wednesday, December 14, 2011 3:07 AM
  • User3866881 posted

    I'm interested in the public property option of which you speak as I'm not familiar with that technique. Can you elaborate? Mike

    Hello:)

    Of course to tell you something like this——

    public class ForecastDayColumn : ITemplate
      
    {
              private string _cssName=null;
              public string CssName
               {
                       get
                        {
                              return _cssName;
                       }
                      set
                        {
                             ViewState["cssName"]=value;
                        }
               }

       }

    And then in the binding code——

     // This next line is where I think I should be setting the css-class function
                   startSummary
    .Text = "<div id=\"summary" + m_colNumber + "\" align=\"right\" class=\"+CssName;

    You should initialize the instance by assigning the value to CssName before you use it。

    Best reguards!

    Wednesday, December 14, 2011 3:38 AM
  • User-2024822571 posted

    Ah,

    I see where you're comming from now. The problem as I see it is that I don't know the values required to complete the test at the time of generating the column (or do I? I'll need to check this). As a result I don't think I can set the style on column creation and may need to do it at databinding time. As you can tell i'm getting more uncertain about the data availability as I write this so I'll go away and check before putting my foot in my mouth.

    Wednesday, December 14, 2011 4:05 AM
  • User-2024822571 posted

    You know what...

    I think you might just be onto something here. At the time I am requesting a new column to be created I do have the data to hand. It's not currently in a format that is useable for my test, but it's beyond my skills to get it in that state and hence make it useable.

    Thanks for the suggestion. I'll give it a try and let you know if this answers my question.

    Wednesday, December 14, 2011 4:19 AM
  • User-2024822571 posted

    I've now discovered the thing that was nagging in the back of my mind. When I create the columns I add to them a template field (hence the ITemplate). I only run the column generation code against one object (its all I need in order to generate the columns) but each object maps to a row in the grid, so there may be more than one row. If I set the class at the time of defining the column I do so for all rows and this is not correct. I need each cell in each row to perform the test and to apply the appropriate style. This is why I was trying to do it at data binding time via a function.

    Is there another way to do this?

    Wednesday, December 14, 2011 6:33 AM
  • User1062580462 posted

    I suspect that "FormatMovementField" function is in respective Page class. If so, please rewrite it here or in common place from where this can be called.

    If not

    You need current "DataItem" to find the correct class name, you can use DataBinding event of startSummary and update the class name correctly.

    Note: <%#..%> will work only when it directly written in aspx page.

    - Bharath

    Thursday, December 22, 2011 1:47 AM
  • User-2024822571 posted

    Bharath,

    FormatMovementField() is a protected method in the partial class. It is quite simpley:

    protected String FormatMovementField(Int32 value)
          {
             if (value > 0)
             {
                return "notEnoughStock";
             }
             else
             {
                return "enoughStock";
             }
          }

    When you say "You need current DataItem to find the correct class name". What do you mean? Do you mean the current row? Do you have an example of how you would use this once it has been identified in order to set the class?

    Mike

     

    Tuesday, January 3, 2012 8:54 AM