Reputation: 665
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.
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
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
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
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
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