views:

76

answers:

3

Hello. I have a gridview which takes in data from 3 tables. And this gridview also have an additional column called "Role" which is not included in the database. Currently, without adding any logic but simply using the findcontrol to the label, "Role", i can show out "ML" But, when I add in the logic, it did not appear at all.

In any case, does anyone knows how to insert "ML" into the "Role" column which is not found in the database but is reference from another column found in the database.

This is the codes used to display the "ML" in the role column.

protected void gridAMDisplay_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        //find the Label control using FindControl and set its Text on some column value
        DataRowView row = (DataRowView)e.Row.DataItem;

        if (!DBNull.Value.Equals(row["ModuleLeader"]))
        {

            if (row["ModuleLeader"].ToString() == "ModuleStr")
            {
                Label lbl = e.Row.FindControl("lblRole") as Label;
                if (lbl != null)
                {
                    lbl.Text = "ML";
                }
            }
        }
    }
}

This part of the code when comment off, the ML can be displayed in the role column, otherwise, nothing is displayed. Therefore, i feel that the findcontrol part works. BUT, referencing does not works.

if (row["ModuleLeader"].ToString() == "ModuleStr")
            {

As i mentioned, the role column was not included in any of the tables in the DB. Therefore, i added in this codes.

<asp:TemplateField HeaderText="Role">
    <ItemTemplate>
        <asp:Label ID="lblRole" runat="server" Text="" />
    </ItemTemplate>
</asp:TemplateField>

But, the problem i have now is, the role column does not reference to the column it is supposed to, which is "Module Leaders"

A: 

You reference the DataItem, which cannot be used in DataBound, you should use OnDataBinding to implement this.

Jan Jongboom
how do i use onDataBinding? Can you provide me with an example please.
Nana
A: 

The best practice in my humble opinion is to create your own template.

Here is one for your case :

public class NotEmptyValueFromDataTemplate : System.Web.UI.Page, IBindableTemplate
{
    protected string p_DataFieldToLookAt;
    protected string p_ValueToPlaceInIfNotNull;
    protected Literal p_litControl;

    public RoleTemplate(string DataFieldToLookAt, string ValueToPlaceInIfNotNull)
    {
        this.p_DataFieldToLookAt = DataFieldToLookAt;
        this.p_ValueToPlaceInIfNotNull = ValueToPlaceInIfNotNull;
    }

    public virtual void OnInit(object sender, EventArgs e)
    { }

    #region IBindableTemplate Members

    public System.Collections.Specialized.IOrderedDictionary ExtractValues(Control container)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ITemplate Members

    public void InstantiateIn(Control container)
    {
        p_litControl = new Literal();
        p_litControl.ID = p_DataFieldToLookAt; /* we don't really care */
        p_litControl.Init += new EventHandler(OnInit);
        p_litControl.DataBinding += new EventHandler(p_litControl_DataBinding);
        container.Controls.Add(p_litControl);
    }

    void p_litControl_DataBinding(object sender, EventArgs e)
    {
        var Data = ((GridViewRow)(p_litControl.NamingContainer)).DataItem;

        string ValueFromData = Convert.ToString(DataBinder.Eval(Data, p_DataFieldToLookAt));

        if(!String.IsNullOrEmpty(ValueFromData))
            p_litControl.Text = p_ValueToPlaceInIfNotNull;
    }

    protected override void OnDataBinding(EventArgs e)
    {
        base.OnDataBinding(e);
    }

    #endregion
}

You have then to instantiate each template row :

protected void GridView3_Init(object sender, EventArgs e)
{
    ((TemplateField)(GridView3.Columns[/* Column Index Here*/])).ItemTemplate = new     NotEmptyValueFromDataTemplate("ModuleLeader", "ML");
}

Last, create the template item in the gridview :

<asp:TemplateField HeaderText="Role"></asp:TemplateField>

Hope it helps, greetings from france, Tarik.

PS : Code is untested and written out of solution

A: 

It seems you only want the role column to update to "ML" based on the data present in another column of the same row. Why not just drop it in the XHTML?

<asp:TemplateField HeaderText="Role"> 
    <ItemTemplate> 
        <asp:Label ID="lblRole" runat="server" Text='<%# GetRoleString(Eval("ModuleLeader"))%>' /> 
    </ItemTemplate> 
</asp:TemplateField> 

Then in the code behind you could have a method:

string GetRoleString(string moduleLeader) 
{
     return (moduleLeader == "ModuleStr") ? "ML" : "";
}

This would occur on databinding and would only happen once per row.

Joel Etherton