asp.netdata-bindinggridviewheadertext

Need dynamic Gridview header text from Parent control's data


Here is the scenario I'm trying to implement.

I have a list of Product objects, each of which has a list Price objects. I'm trying to display this data by using a DataList, where each element of the DataList is a GridView for a Product, displaying the Prices for that Product.

I have everything working great, except for one strange requirement: I need to show the Product name in the header of the first column of each Gridview.

There are numerous questions on SO about dynamically changing the HeaderText of a GridView, but this situation seems a little different since I need to set it to a databound value of a parent control.

My first attempt was to set the GridView Column[0] header text in the ItemCreated event of the DataList. This didn't work because they would all disappear after postback.

Thanks for your help!


Solution

  • Maybe there is an easier way-- but you can work your up to get the DataItem for the parent.

    <asp:DataList runat="server" DataSource="<%#TheProducts %>">
        <ItemTemplate>
            <asp:GridView DataSource='<%#((Product)Container.DataItem).Prices %>' runat="server" AutoGenerateColumns="false">
                <Columns>
                   <asp:TemplateField>
                        <ItemTemplate><%#((Product)((DataListItem)(((GridViewRow)Container).Parent).DataItemContainer).DataItem).Name%></ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField>
                        <ItemTemplate><%#Container.DataItem %></ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </ItemTemplate>
    </asp:DataList>
    

    Code behind would look like this:

    protected List<Product> TheProducts
    {
        get { return new List<Product>
                         {
                             new Product{Name="A", Prices = new List<int>{1,2,4}},
                             new Product{Name="B", Prices = new List<int>{5,6,7}}
                         }; 
        }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!this.IsPostBack)
            this.DataBind();
    }
    

    and Product class might look like this:

    public class Product
    {
        public string Name { get; set; }
    
        private List<int> _prices = null;
        public List<int> Prices
        {
            set { this._prices = value; }
            get
            {
                if(_prices == null)
                    this.Prices = new List<int>();
                return _prices;
            }
        }
    }