我有一个绑定到对象数据源的gridview控件。除了我要显示的列,我想显示此
<Columns>
<asp:CheckBoxField DataField="Locked" Visible="true" AccessibleHeaderText="On Hold" ReadOnly="false"/>
</Columns>
这里有几个问题: 1.如果我执行上述操作,我的页面会加载,某些行的记录会被标记为已检查,而某些行则不会按照数据进行标记。但是,用户无法单击任何记录来撤消其复选标记。它似乎处于禁用状态。
这个复选框字段似乎没有onclick事件。我想在用户检查或取消选中每条记录时立即更新我的记录。这是糟糕的设计,但我的双手并列
如果我在<asp:checkbox>
内使用<itemtemplate>
如何将其绑定到对象数据源中的锁定列,或者我必须通过覆盖方法来实现这一点gridview控件?
答案 0 :(得分:4)
要回答#2,我会在<asp:CheckBox>
中使用<ItemTemplate>
控件,然后在Checked
事件中设置GridView_RowDataBound
属性:
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;
}
}
对于问题#1,我过去使用过的一个解决方案是一个好的结果是让onClick
的客户端<asp:CheckBox>
事件调用一个ASP.NET Ajax异步页面方法(本质上是一个私有Web服务),用于更新相应的业务对象。这对您来说不是最简单的方法,但用户的体验非常灵活(即没有整页回发):
您需要在代码隐藏文件中使用静态方法来更新相应的业务对象。像(这很粗糙)的东西:
[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." );
}
}
有关如何使用ASP.NET Ajax执行此操作的详细信息,请check out MSDN here。
答案 1 :(得分:0)
对于click事件,我无法弄清楚OnClickChange,所以我自己动手。
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()
{
}
}
}
至于数据绑定和更新,我只是自己在GridRowCommand上处理它。
答案 2 :(得分:0)
您的控件已被锁定,因为如果行处于编辑模式,GridView将只允许您编辑行。我认为你真正想要的是一个在TemplateField中定义的复选框。然后,您可以在后面的代码中设置初始“已检查”值,或者执行以下操作:
<asp:CheckBox ID="MyCheckBox" runat="server" Checked='<%#Eval("Locked")' ... />
对于触发器,您可以将OnCheckedChange属性指向您选择的函数,但我不确定您是如何告诉它检查哪一行。
更好的选择可能是使用Button或ImageButton控件来执行相同的操作。这样你可以使用行ID或任何你需要的东西填充CommandArgument,当你处理GridView的RowCommand时,你可以访问它。