在ASP.NET 2.0中操作数据之四十九:为GridView控件添加RadioButt
这样做的原因在于:在客户端,便于浏览器区分每个rendered control(比如本章的radio button);在网络服务器端,便于服务器区分当页面回传时发生了什么事件或改变。比如,无论何时,当一个 RadioButton的选中状态(checked state)发生改变时,我们希望运行某些服务器端代码。为此,我们可以将RadioButton的AutoPostBack属性设置为true,同时为CheckChanged事件创建一个事件处理器。如果每个radio buttons的name和id值相同的话,当发生页面回转时,我们不能确定到底点击了哪个RadioButton。 这样做的缺点在于,我们不能用RadioButton Web 控件在GridView里创建一个radio button列。因此,我们必须在GridView row里添加适当的代码。 注意:和RadioButton Web控件一样,当把radio button HTML控件添加到模板时,它也会包含唯一的名称特征。如果你不熟悉HTML控件,没关系,因为很少使用它,尤其在ASP.NET 2.0里。如果有兴趣了解更多,见 K. Scott Allen的博客里的文章Web Controls and HTML Controls. 用Literal控件注入Radio Button代码 为了在GridView控件里对radio buttons进行聚合,我们要在ItemTemplate模板里手动注入radio button代码。每个radio button具有相同的name特性,但id特性必须是唯一的(因为我们可能需要通过客户端脚本访问某个radio button)。因为当用户选择了一个radio button,页面回传后,浏览器将返回该按钮的一个值,所以每个radio button要具备一个唯一值特性(unique value attribute)。最后,当选择一个radio button后,我们应确保为该按钮添加checked属性。另外,用户做了选择并发生回传后,radio button将回到默认状态(可任意指定)。 可以有2种方法在模板里注入代码。其中一种是在代码里调用定义在后台代码类(code-behind class)里的方法,并使用格式化的形式。这个方法我们在教程《在GridView控件中使用TemplateField》里论述过。在本例,代码看起来像这个样子: <input type="radio" id='<%# GetUniqueRadioButtonID(...) %>' name='SuppliersGroup' value='<%# GetRadioButtonValue(...) %>' ... /> 其中,GetUniqueRadioButton和GetRadioButtonValue是定义在后台代码类里的方法,其作用是返回特定的id和value值。用这种可以对radio button的id属性和 value属性赋值,但不能对checked属性赋值。因为只有当数据第一次绑定到该GridView控件时,数据绑定语法才能成功执行。所以只有当启用GridView的试图状态,并且是第一次登录页面(或者明确的让GridView重新绑定数据源)时这种格式化的方法才能奏效。所以,当页面发生回传时,对checked属性赋值的这个功能是失效的。这个问题有点超出了本教程的范围,所以在这里我将它搁置一边,然而我仍然鼓励你用上面的这个方法。这个练习将使你更深入的理解GridView以及数据绑定的生命周期。 第2种,也是本教程要用的方法是在模板里添加一个Literal控件。在GridView的RowCreated或RowDataBound事件处理器里,我们可以通过编程来访问Literal控件,并设置其Text属性。 在TemplateField的ItemTemplate模板里,移除RadioButton控件,换成Literal控件,设其ID为RadioButtonMarkup。 然后,为GridView的RowCreated事件创建事件处理器。RowCreated事件是这样的,不管数据是不是重新绑定到GridView,只要在GridView里新增一行记录就将引发RowCreated事件。那意味着,当发生回传事件时,哪怕数据来自视图状态,也会引发RowCreated事件。我们使用RowCreated事件而不使用RowDataBound事件的原因在于,只有当数据明确的绑定到数据Web控件时才会引发RowDataBound事件.
protected void Suppliers_RowCreated(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { // Grab a reference to the Literal control Literal output = (Literal)e.Row.FindControl("RadioButtonMarkup"); // Output the markup except for the "checked" attribute output.Text = string.Format( @"<input type="radio" name="SuppliersGroup" " + @"id="RowSelector{0}" value="{0}" />", e.Row.RowIndex); } } 当选择GridView控件的某条记录时,我们关心的是该供应商的SupplierID值。我们首先会想到让radio button的value属性返回该SupplierID值(而不是该条记录的index值)。然而这样盲目地获取并传递一个SupplierID值是很危险的。以我们的GridView控件为例,它列出了所有的美国供应商,如果我们直接通过radio button来传递SupplierID,我们无法阻止一个带有恶意的用户对回传过来的SupplierID造假。通过将value属性设置为某条记录的index值,当发生页面回传时,从DataKeys集合里获取该供应商的SupplierID值。这样的话,我们就能确保用户只能使用GridView里某个供应商的对应的SupplierID值。 添加完事件处理器代码后,花几分钟在浏览器里测试该页面,首先确保每次只能选择一个radio button。然而,当选择一个radio button并点击下面的按钮,在页面发生回传后,所有的radio button都回到最初的状态(意即,发生回传后,选中的radio button又恢复未选状态)。怎样解决这个问题呢?我们在RowCreated事件处理器里添加代码,先确定发生页面回传后,选中的那个radio button的index值,然后添加checked="checked"属性。 (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |