asp:GridView中的CheckBoxField - VS 2008

时间:2009-01-08 19:29:33

标签: c# asp.net

我有一个绑定到对象数据源的gridview控件。除了我要显示的列,我想显示此

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

这里有几个问题: 1.如果我执行上述操作,我的页面会加载,某些行的记录会被标记为已检查,而某些行则不会按照数据进行标记。但是,用户无法单击任何记录来撤消其复选标记。它似乎处于禁用状态。

  1. 这个复选框字段似乎没有onclick事件。我想在用户检查或取消选中每条记录时立即更新我的记录。这是糟糕的设计,但我的双手并列

  2. 如果我在<asp:checkbox>内使用<itemtemplate>如何将其绑定到对象数据源中的锁定列,或者我必须通过覆盖方法来实现这一点gridview控件?

3 个答案:

答案 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时,你可以访问它。