Barnabeck
Barnabeck

Reputation: 481

RowDataBound not acting the way I expect

I have a Gridview with an ImageButton that should become visible for the selected row only. I'm doing this in the OnRowDataBound event, but it doesn't work.

protected void OnRowDataBoundMS(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        if ((e.Row.RowState & DataControlRowState.Edit) > 0)
        {
            // some working code that handles the edit mode
        }
        else if (Gridview1.SelectedValue != null)
        {
            ImageButton ImgBut1 = e.Row.FindControl("ButtonUp") as ImageButton;
            ImgBut1.Visible = true;
        }
    }
}

My gridview looks like this:

    <asp:GridView runat="server"
                  ID="Gridview1"
                  DataSourceID="Milestones"
                  DataKeyNames="ID"
                  AutoGenerateColumns="false"
                  OnRowEditing="OnRowEditing"
                  OnRowDataBound="OnRowDataBoundMS"
                  OnSelectedIndexChanged="OnSelectedIndexChangedMS">
    ...
        <asp:templatefield HeaderText="Order" ItemStyle-HorizontalAlign="center">
            <ItemTemplate>
                <asp:ImageButton ID="ButtonUp" runat="server" OnClick ="OrderUp"  ImageUrl="img/up.png" Visible="false"/>
            </ItemTemplate>
        </asp:templatefield>

I spent the last 3 hours on this and I start to freak out. Any hints on this? Martin

Upvotes: 0

Views: 615

Answers (3)

Brian Mains
Brian Mains

Reputation: 50728

The other alternative is to use the SelectedIndexChanged event if you are using the Select command option:

protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
    foreach (GridViewRow row in GridView1.Rows)
    {
        Control ctl = row.FindControl("ButtonUp");
        ctl.Visible = (row.RowState & DataControlRowState.Selected) != 0;
    }
}

Something like that; RowDataBound may fire before the selected index gets updated (not sure about that...).

Upvotes: 3

Barnabeck
Barnabeck

Reputation: 481

I guess the key comment is what Brian Mains said about the RowDataBound firing before the selected Index gets updated. I can't prove this to be generally right, but it seems so. Therefore all attempts, even following ConnersFan suggestions didn't worked out. I did what Brian suggested and used the SelectedIndexChanged event handler, but without looping through all rows. The solution is actually quite simple:

protected void OnSelectedIndexChangedMS(object sender, EventArgs e)
{
    Gridview1.DataBind();
    ImageButton ImgBut1 = Gridview1.SelectedRow.FindControl("ButtonUp") as ImageButton;
    ImgBut1.Visible = true;
}

Upvotes: 1

Martin Parenteau
Martin Parenteau

Reputation: 73731

You can detect the selected row in the RowDataBound event handler with the RowState property, the same way you detect the edit row:

if ((e.Row.RowState & DataControlRowState.Selected) != 0)
{
    ...
}

An alternative is to set the Visible property of the ImageButton in the markup, with a data-binding expression:

<asp:ImageButton runat="server" Visible='<%# ((Container as GridViewRow).RowState & DataControlRowState.Selected) != 0 %>' ... />

Note: make sure that you call GridView1.DataBind() in the SelectedIndexChanged event handler, in order to refresh the content of the GridView.

Upvotes: 2

Related Questions