user38230
user38230

Reputation: 665

asp:CheckBoxField in GridView - VS 2008

I have a gridview control bound to an object data source. in addition to the columns that i want to display i want to display this

 <Columns>
         <asp:CheckBoxField DataField="Locked" Visible="true" AccessibleHeaderText="On Hold" ReadOnly="false"/>
 </Columns>

Couple of questions here: 1. If I do the above said, my page loads and certain rows have their records marked as checked and certain rows do not, as per data. However, the user is unable to click on any records to undo their check marks. It appears that this is in a disabled state.

  1. It seems there is no onclick event with this checkboxfield. I want to update my records instantly when the user checks or unchecks each record. yes bad design here but my hands are tied

  2. If i were to go with <asp:checkbox> within an <itemtemplate> how do i bind that to my locked column within the object datasource or do i have to do that by overiding onne of the methods of the gridview control?

Upvotes: 2

Views: 7082

Answers (3)

Matt Peterson
Matt Peterson

Reputation: 5749

To answer #2, I would go with a <asp:CheckBox> control in the <ItemTemplate> and then set the Checked property in the GridView_RowDataBound event:

protected void grdSomething_RowDataBound ( Object sender, GridViewRowEventArgs e )
{
    if ( e.Row.RowType == DataControlRowType.DataRow )
    {
        BusinessObject data = ( BusinessObject ) e.Row.DataItem;
        CheckBox chkLocked = ( CheckBox ) e.Row.FindControl( "chkLocked" );
        chkLocked.Checked = data.Locked;
    }
}

As for question #1, one solution that I've used in the past with good results is to have the client-side onClick event of the <asp:CheckBox> call an ASP.NET Ajax asynchronous page method (essentially a private web service) that updates the appropriate business object. This wouldn't be the simplest approach for you, but the user's experience is pretty slick (i.e. no full-page postback):

You would need a static method in your code-behind file to update the appropriate business object. Something like (this is pretty rough):

[WebMethod]
public static void ToggleLockedStatus ( string key )
{
    if ( BusinessObjectDictionary.ContainsKey( key ) )
    {
        BusinessObjectDictionary[ key ].Locked = !BusinessObjectDictionary[ key ].Locked;
    }
    else
    {
        throw new Exception( "The business object specified was not found." );
    }
}

For details on how to do this with ASP.NET Ajax, check out MSDN here.

Upvotes: 4

gfrizzle
gfrizzle

Reputation: 12609

Your control is locked because the GridView will only let you edit a row if the row is in Edit mode. I think what you're really looking for is a checkbox defined in a TemplateField. Then you can either set the initial "checked" value in the code behind or by doing something like:

<asp:CheckBox ID="MyCheckBox" runat="server" Checked='<%#Eval("Locked")' ... />

As for the trigger, you can point the OnCheckedChange property to the function of your choosing, but I'm not sure how you'd tell it which row was checked.

A better alternative could be to use the Button or ImageButton control to do the same thing. That way you can populate the CommandArgument with the row ID or whatever you need and you'll have access to it when you handle the RowCommand of the GridView.

Upvotes: 0

David Basarab
David Basarab

Reputation: 73301

For the click Event I could not figure out the OnClickChange either, so I rolled my own.

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Web;
using System.Web.UI.WebControls;


namespace Web.Library.Controls.Commands
{
    public class CommandCheckBox : System.Web.UI.WebControls.CheckBox
    {
        private static readonly object EventCommand = new object();

        public event CommandEventHandler Command
        {
            add
            {
                Events.AddHandler(EventCommand, value);
            }
            remove
            {
                Events.RemoveHandler(EventCommand, value);
            }
        }

        public string CommandName
        {
            get
            {
                if (this.ViewState["CommandName"] == null)
                    return string.Empty;

                return (string)this.ViewState["CommandName"];
            }
            set { this.ViewState["CommandName"] = value; }
        }

        public string CommandArgument
        {
            get
            {
                if (this.ViewState["CommandArgument"] == null)
                    return string.Empty;

                return (string)this.ViewState["CommandArgument"];
            }
            set { this.ViewState["CommandArgument"] = value; }
        }

        protected virtual void OnCommand(CommandEventArgs args)
        {
            CommandEventHandler commandEventHand = Events[EventCommand] as CommandEventHandler;

            if (commandEventHand != null)
            {
                commandEventHand(this, args);
            }

            base.RaiseBubbleEvent(this, args);
        }

        protected override void OnCheckedChanged(EventArgs e)
        {
            base.OnCheckedChanged(e);

            CommandEventArgs args = new CommandEventArgs(this.CommandName, this.CommandArgument);

            this.OnCommand(args);
        }


        public CommandCheckBox()
        {
        }

    }
}

As for the databind and updating I just handled it myself on GridRowCommand.

Upvotes: 0

Related Questions