本帖最后由 木头 于 2014-5-12 13:04 编辑
第一次接触AspxGridView 的时候觉得他真的是一个非常强大的第三方控件,应该可以和telerik齐名了,后来听说他是全球使用率最高的,在国内也是使用量最大的。但是,唯一美中不足就是编译后生产阶段产生的html真的大的吓死人,ViewState关掉似乎也没有多大作用。不过算了,为了保持控件本身炫丽的效果,那些不足暂时不管了。毕竟带宽以后只会越来越好。闲话少说,上内容:
一、AspxGridView 的行编辑效果非常的帅,但是当我第一次使用的时候真的是一波三者。大概问题有几个:
1、不知道怎么获取自动生成的那些控件
2、不知道怎么去验证
3、不知道怎么去输出验证的错误
总之很多不知道,而且感觉自己也语无伦次,那么就今天的新发现说说吧。
首先,为了更方便的定制显示效果和要编辑的部分数据,我们需要使用EditFrom,在EditForm中可以非常容易的使用table或者div进行页面布局,这里就以Table 为例:
最终显示效果
这里定义了5个GridViewDataColumn,但是当我们进行编辑的时候不想显示创建时间,所以用EditForm就对了,效果如下:
上代码:
[HTML] 纯文本查看 复制代码 <EditForm>
<table style="width: 100%;">
<tr>
<td class="EditCellLeft">字典分类名称</td>
<td>
<dx:ASPxTextBox runat="server" ID="txtDicCategoryName" Width="100%" Text='<%# Bind("DicCategoryName" ) %>'>
<ValidationSettings ValidationGroup="editForm" ErrorDisplayMode="ImageWithTooltip">
<RequiredField IsRequired="True" ErrorText="字典分类名称不能为空"></RequiredField>
</ValidationSettings>
</dx:ASPxTextBox>
</td>
<td class="EditCellLeft">字典分类备注</td>
<td>
<dx:ASPxTextBox runat="server" ID="txtDicCategoryMemo" Width="100%" Text='<%# Bind("DicCategoryMemo" ) %>'></dx:ASPxTextBox>
</td>
</tr>
<tr>
<td class="EditCellLeft">
字典分类标识
</td>
<td>
<dx:ASPxTextBox runat="server" ID="txtDicCategoryKey" Width="100%" Text='<%# Bind("DicCategoryKey" ) %>'>
<ValidationSettings ValidationGroup="editForm" ErrorDisplayMode="ImageWithTooltip">
<RequiredField IsRequired="True" ErrorText="字典分类标识不能为空"></RequiredField>
</ValidationSettings>
</dx:ASPxTextBox>
</td>
<td class="EditCellLeft">分类标识码</td>
<td>
<dx:ASPxTextBox runat="server" ReadOnly="True" ID="txtDicCategoryCode" Width="100%" Text='<%# Bind("DicCategoryCode" ) %>'>
</dx:ASPxTextBox>
</td>
</tr>
<tr>
<td colspan="2">
<dx:ASPxLabel runat="server" ID="lbValidationInfo"/>
</td>
<td colspan="2" class="EditButton">
<a href="javascript:void(0);">更新</a>
<a href="javascript:void(0);">取消</a>
</td>
</tr>
</table>
</EditForm>
相应的,如果我们有些数据字段是在列表中不希望被显示,但是在编辑状态下又希望被显示的,我们可以这样设置绑定的属性,比如设置某一个绑定列的显示模式为false,但是编辑模式的显示效果为true,如下:
Visible="False" EditFormSettings-Visible="True"
接着下面的,很多文章都建议使用以下方法放置Update 和Cancel
<dx:ASPxGridViewTemplateReplacement ID="UpdateButton" ReplacementType="EditFormUpdateButton" runat="server">
</dx:ASPxGridViewTemplateReplacement>
<dx:ASPxGridViewTemplateReplacement ID="CancelButton" ReplacementType="EditFormCancelButton" runat="server">
</dx:ASPxGridViewTemplateReplacement>
但是这样的问题很多,最严重的一个问题就是,我们是中国人哦,换成更新和取消怎么换呢,当然,也有办法的,可以在Setingtex属性里面,不过我现在想对EditForm里面的控件进行验证时怎么办呢,至少我现在还没找到什么好的办法,所以,我屏蔽了上述方法,直接加了2个A标签,通过前台js去触发验证,然后提交编辑:
[size=13.63636302947998px] <a href="javascript:void(0);" onclick="OnUpdateClick(this)">更新</a>
[size=13.63636302947998px] <a href="javascript:void(0);" onclick="OnCancelClick(this)">取消</a>
[size=13.63636302947998px]
脚本其实也很简单:
<script type="text/javascript">
function OnUpdateClick(editor)
{
if (ASPxClientEdit.ValidateGroup("editForm"))
gridView.UpdateEdit();
}
function OnCancelClick() {
gridView.CancelEdit();
}
</script>
ValidateGroup,这个属性很重要,前天要把需要验证的控件这个ValidateGroup属性设置成相同的,然后才能触发验证。例如,这里:
[size=13.63636302947998px]<dx:ASPxTextBox runat="server" ID="txtDicCategoryName" Width="100%" Text='<%# Bind("DicCategoryName" ) %>'>
[size=13.63636302947998px] <ValidationSettings ValidationGroup="editForm" ErrorDisplayMode="ImageWithTooltip">
[size=13.63636302947998px] <RequiredField IsRequired="True" ErrorText="字典分类名称不能为空"></RequiredField>
[size=13.63636302947998px] </ValidationSettings>
[size=13.63636302947998px] </dx:ASPxTextBox>
[size=13.63636302947998px]
在ValidationSettings 中的ValidationGroup设置成你想命名的验证组,这样就可以在点击更新按钮的时候触发你定义的验证了哦。
剩下的就是后台的了,我现在需要实现如下的效果:
1、在进行行编辑的时候需要对数据进行验证,这个时候需要用到AspxGridView的RowValidating方法:直接上图了,比较头疼哦,
[size=13.63636302947998px]protected void gridView_RowValidating(object sender, DevExpress.Web.Data.ASPxDataValidationEventArgs e)
[size=13.63636302947998px] {
[size=13.63636302947998px] if (e.IsNewRow)
[size=13.63636302947998px] {
[size=13.63636302947998px] var entity = new Entity.SysDictionaryCategory
[size=13.63636302947998px] {
[size=13.63636302947998px] DicCategoryName = e.NewValues["DicCategoryName"].ToString(),
[size=13.63636302947998px] DicCategoryKey = e.NewValues["DicCategoryKey"].ToString(),
[size=13.63636302947998px] DicCategoryMemo = e.NewValues["DicCategoryMemo"].ToString(),
[size=13.63636302947998px] DicCategoryCode = e.NewValues[gridView.KeyFieldName].ToString(),
[size=13.63636302947998px] CreateTime = DateTime.Now
[size=13.63636302947998px] };
[size=13.63636302947998px] if (
[size=13.63636302947998px] BLL.SysDictionaryCategory.GetInstance()
[size=13.63636302947998px] .ExistsSysDictionaryCategoryByDicCategoryName(entity.DicCategoryName, entity.DicCategoryKey))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError = "存在相同名称或者标识的数据,请变更用户名或标识名称";
[size=13.63636302947998px] return;
[size=13.63636302947998px] }
[size=13.63636302947998px] if (!BLL.SysDictionaryCategory.GetInstance().Insert(entity))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError = "数据添加失败,请重试或联系管理员";
[size=13.63636302947998px] }
[size=13.63636302947998px] }
[size=13.63636302947998px] else
[size=13.63636302947998px] {
[size=13.63636302947998px] if (e.OldValues["DicCategoryName"].Equals(e.NewValues["DicCategoryName"]) &&
[size=13.63636302947998px] e.OldValues["DicCategoryKey"].Equals(e.NewValues["DicCategoryKey"]))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError += "分类名称错误:字典分类名称没有变化;分类字典标识错误:字典分类名称标识没有变化";
[size=13.63636302947998px] return;
[size=13.63636302947998px] }
[size=13.63636302947998px] if (e.OldValues["DicCategoryCode"].ToString().Equals(string.Empty))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError += "字典分类编码不能为空;";
[size=13.63636302947998px] return;
[size=13.63636302947998px] }
[size=13.63636302947998px] var dicCategoryName = e.NewValues["DicCategoryName"].ToString();
[size=13.63636302947998px] var dicCategoryKey = e.NewValues["DicCategoryKey"].ToString();
[size=13.63636302947998px] var key = e.Keys[gridView.KeyFieldName].ToString();
[size=13.63636302947998px] try
[size=13.63636302947998px] {
[size=13.63636302947998px] if (
[size=13.63636302947998px] BLL.SysDictionaryCategory.GetInstance()
[size=13.63636302947998px] .ExistsSysteDictionaryCategoryByDicCategoryNameAndDicCategoryCode(dicCategoryName,
[size=13.63636302947998px] dicCategoryKey,
[size=13.63636302947998px] key))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError = "存在相同的字典名称或者字典名称标识,更新操作被迫取消";
[size=13.63636302947998px] }
[size=13.63636302947998px] else
[size=13.63636302947998px] {
[size=13.63636302947998px] var entity =
[size=13.63636302947998px] BLL.SysDictionaryCategory.GetInstance().GetEntity(e.Keys["DicCategoryCode"].ToString());
[size=13.63636302947998px] entity.DicCategoryName = dicCategoryName;
[size=13.63636302947998px] entity.DicCategoryKey = dicCategoryKey;
[size=13.63636302947998px] entity.DicCategoryMemo = e.NewValues["DicCategoryMemo"].ToString();
[size=13.63636302947998px] entity.CreateTime = DateTime.Now;
[size=13.63636302947998px] if (!BLL.SysDictionaryCategory.GetInstance().Update(entity))
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError = "字典分类信息更新失败,请重试或者联系管理员解决";
[size=13.63636302947998px] }
[size=13.63636302947998px] }
[size=13.63636302947998px] }
[size=13.63636302947998px] catch
[size=13.63636302947998px] {
[size=13.63636302947998px] e.RowError = "系统异常,请重试或者联系管理员解决";
[size=13.63636302947998px] }
[size=13.63636302947998px] }
[size=13.63636302947998px] }
这样的效果非常好,一但验证出错,效果就如下哦:
好性感哦。个人觉得比JS 的Alert()效果要好的多。
更新需要用到RowUpdating方法:直接贴代码了,其实更新事件我是直接 定义到验证事件里面了,常规验证应该在RowUpdating事件中去设置RowError的文本,其实也很简单,只要抛出异常,例如在RowUpdating 中抛出 throw new Exception("验证错误"),同意可以实现上图的验证效果,我之所以全部放在rowupdating中是因为个人比较不喜欢在代码中抛出异常,感觉比较生硬。 那么真正的在RowUpdating中,我们只需重新绑定数据,然后设置些惯性做法:
e.Cancel = true;
gridView.CancelEdit();
BindGridView();
第一句必须的哦,不然会报不支持指定的方法这个错误。
第二行就是取消当前编辑状态,回到正常列表视图
第三个,重新绑定数据了哦。
删除方法,RowDeleting:
[size=13.63636302947998px] protected void gridView_RowDeleting(object sender, DevExpress.Web.Data.ASPxDataDeletingEventArgs e)
[size=13.63636302947998px] {
[size=13.63636302947998px] var key = e.Keys[gridView.KeyFieldName].ToString();
[size=13.63636302947998px] if (!BLL.SysDictionaryCategory.GetInstance().Delete(key + "sdf"))
[size=13.63636302947998px] return;
[size=13.63636302947998px] e.Cancel = true;
[size=13.63636302947998px] gridView.CancelEdit();
[size=13.63636302947998px] BindGridView();
[size=13.63636302947998px] }
很多人会问key+sqf是什么意思,其实那个后面的“sdf”一点意义都没有,是我测试的时候想让它抛出异常,或者执行不成功。但是执行的时候还是正确的,这是因为什么?其实很简单,参数是通过参数化的方式传输的,key的值已经是32位字符了,所以后面加什么都会被截断。这就是参数化的好处啊,呵呵。上面代码很简单,不说了。
添加方法:
[size=13.63636302947998px]protected void gridView_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e)
[size=13.63636302947998px] {
[size=13.63636302947998px] e.Cancel = true;
[size=13.63636302947998px] gridView.CancelEdit();
[size=13.63636302947998px] BindGridView();
[size=13.63636302947998px] }
是不是也很简单,因为在验证事件的过程中已经执行了。这个里面用到了一个知识点,就是当我初始化一个新加行的时候希望默认对标识编码进行赋值,效果如下:
初始化这个值,需要用到这个方法:InitNewRow
[size=13.63636302947998px]protected void gridView_InitNewRow(object sender, DevExpress.Web.Data.ASPxDataInitNewRowEventArgs e)
[size=13.63636302947998px] {
[size=13.63636302947998px] e.NewValues[gridView.KeyFieldName] = StringFunction.GetInstance().GetGuidString();
[size=13.63636302947998px] }
[size=13.63636302947998px][size=13.63636302947998px]唉,路漫漫,对我一个新手来说,能研究出这么多不容易了,后面有新的知识在跟大家一起分享哈。
[size=13.63636302947998px][size=13.63636302947998px]
|