DotVVM Business Pack GridView:验证与表单编辑问题咨询
DotVVM GridView 内联验证与表单编辑方案
一、内联插入/编辑的验证方案(支持数据注解+自定义验证)
1. 数据注解验证的正确配置
你当前代码的验证目标绑定有误——内联编辑/插入时,验证应该针对当前编辑的单行实体,而非整个Bloods数据源集合。
修正要点:
- 先在实体类(比如
Blood)的属性上添加数据注解,例如给BloodProductID加必填验证:[Required(ErrorMessage = "产品不能为空")] public int BloodProductID { get; set; } - 确保需要验证的GridView列开启
Validation.Enabled="true",并正确绑定Validator.Value(你已经在ComboBoxColumn做了这一步,若Comments等其他字段需要验证,也要对应配置)。 - 保存按钮的
Validation.Target要绑定到当前编辑的行({value: _this}),注意你的代码里该属性少了引号,修正后示例:<bp:Button Text="Save" Type="Success" Click="{command: _parent.SaveNewBlood()}" Visible="{value: _parent.IsBloodInserting}" Validation.Target="{value: _this}" />
2. 自定义验证的实现
如果需要业务规则类的自定义验证,有两种方式:
- 命令内手动添加错误:在ViewModel的保存命令里编写逻辑,将错误加入
ValidationErrors集合:public void SaveNewBlood() { var newBlood = Bloods.InsertRow; // 自定义规则:选择特定产品时备注不能为空 if (newBlood.BloodProductID == 1 && string.IsNullOrWhiteSpace(newBlood.Comments)) { ValidationErrors.Add(nameof(Bloods.InsertRow.Comments), "选择该产品时备注不能为空"); return; } // 执行保存逻辑 Bloods.FinishInsert(); } - 自定义验证特性:用
[CustomValidation]标记实体属性,实现ValidationAttribute子类来封装验证逻辑。
3. 错误显示优化
- 你外层div设置的
Validator.InvalidCssClass="has-error"会自动给验证失败的控件添加样式,配合Bootstrap就能显示错误状态。 - 若要显示具体错误文本,可以在列内添加
dot:ValidationMessage控件:<bp:GridViewComboBoxColumn Validation.Enabled="true" Validator.Value="{value: BloodProductID}" Value="{value: BloodProductID}" DataSource="{value: ProductList }" ItemValueBinding="{value: Value}" ItemTextBinding="{value: Text}" HeaderText="Product"> <ItemTemplate> <dot:ComboBox ... /> <dot:ValidationMessage For="{value: BloodProductID}" class="text-danger" /> </ItemTemplate> </bp:GridViewComboBoxColumn>
二、实现类似DevExpress的表单/Popup编辑模式
DotVVM GridView没有内置PopupEditForm,但可以通过Popup控件+ViewModel绑定快速实现,步骤如下:
1. ViewModel添加绑定属性
public Blood SelectedBlood { get; set; } public bool IsEditPopupOpen { get; set; } public bool IsInsertPopupOpen { get; set; } // 触发编辑弹窗 public void EditBlood(int rowId) { SelectedBlood = Bloods.Rows.First(b => b.RowID == rowId); IsEditPopupOpen = true; } // 保存编辑内容 public void SaveEditedBlood() { // 先验证 if (!IsValid(nameof(SelectedBlood))) return; // 更新数据源 Bloods.UpdateRow(SelectedBlood); IsEditPopupOpen = false; } // 触发插入弹窗 public void OpenInsertPopup() { SelectedBlood = new Blood(); IsInsertPopupOpen = true; }
2. View层添加Popup表单
以Bootstrap Modal为例,实现弹窗编辑/插入:
<!-- 编辑弹窗 --> <div class="modal fade" id="editModal" data-bs-backdrop="static" visible.bind="IsEditPopupOpen" bs-modal> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">编辑血液记录</h5> <button type="button" class="btn-close" click="{command: IsEditPopupOpen = false}"></button> </div> <div class="modal-body" Validation.Target="{value: SelectedBlood}" Validator.InvalidCssClass="has-error"> <div class="mb-3"> <label class="form-label">产品</label> <dot:ComboBox Value="{value: SelectedBlood.BloodProductID}" DataSource="{value: ProductList}" ItemValueBinding="{value: Value}" ItemTextBinding="{value: Text}" Validation.Enabled="true" /> <dot:ValidationMessage For="{value: SelectedBlood.BloodProductID}" class="text-danger" /> </div> <div class="mb-3"> <label class="form-label">备注</label> <dot:TextBox Text="{value: SelectedBlood.Comments}" /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" click="{command: IsEditPopupOpen = false}">取消</button> <button type="button" class="btn btn-success" click="{command: SaveEditedBlood()}" Validation.Target="{value: SelectedBlood}">保存</button> </div> </div> </div> </div> <!-- 插入弹窗(结构与编辑弹窗类似,绑定IsInsertPopupOpen即可) --> <!-- GridView编辑按钮修改 --> <ContentTemplate> <dot:LinkButton Click="{command: _parent.EditBlood(rowID)}"> <bs:Icon Type="pencil" /> </dot:LinkButton> </ContentTemplate> <!-- 原Add Blood按钮修改 --> <bp:Button Text="Add Blood" Click="{command: OpenInsertPopup()}" Visible="{value: !IsInsertPopupOpen}" Validation.Enabled="false" />
这样就能实现点击按钮弹出表单编辑的模式,和DevExpress的PopupEditForm效果一致。
内容的提问来源于stack exchange,提问作者Tim Long
相关产品推荐
相关产品推荐

