You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core DevExtreme表单:同一行分组边框高度统一问题

ASP.NET Core DevExtreme表单分组边框等高解决方案

问题描述

我CSS基础薄弱,现在遇到一个问题:在ASP.NET Core的DevExtreme表单中,同一行内元素数量不同的分组边框高度不一致,希望让Test 1和Test 2分组的边框高度保持相等。

当前效果:Test 1分组仅包含2个表单元素,高度明显低于包含3个元素的Test 2分组,两个分组的边框高度不统一。

当前代码

ASP.NET Core(DevExtreme)代码

<div class="card-custom">
    @(
        Html.DevExtreme().Form<Deposit_LoandepositWithdrawModel>().ID("dxFormReceipt").ReadOnly(false).ColCountByScreen(c => c.Sm(1).Xs(1).Md(3).Lg(4)).LabelMode(FormLabelMode.Floating)
        .Items(item =>
        {
            item.AddGroup().CssClass("BorderCss").Caption("Test 1").ColCountByScreen(c => c.Xs(1).Md(1).Lg(1).Sm(1)).ColSpan(1).Items(grItem => {
                grItem.AddSimpleFor(i => i.PaymentDate).Editor(e => e.DateBox().ID("dateBoxReceiptDatePayDelivery").LabelMode(EditorLabelMode.Floating).Label("Ngày").DisplayFormat("dd/MM/yyyy").UseMaskBehavior(true).DateSerializationFormat("yyyy-MM-dd").Max(DateTime.Now).Min(new DateTime(1990, 1, 1)).Value(DateTime.Now));
                grItem.AddSimpleFor(i => i.PayListNum).Editor(e => e.TextBox().ID("PayListNum_tesst")); 
            }); 
            item.AddGroup().CssClass("BorderCss").Caption("Test 2").ColCountByScreen(c => c.Xs(1).Md(1).Sm(1).Lg(1)).ColSpan(2).Items(grItem => {
                grItem.AddSimpleFor(i => i.PaymentTypeCode).Editor(e => e.RadioGroup().OnValueChanged("onChanged_RadioGroup").DataSource(d => d.Mvc().Controller("Metadata").LoadAction("GetMetadataLoader").LoadMode(DataSourceLoadMode.Raw).LoadParams(new { grouptext = "RECEIPT_TYPE_CODE" }).Key("Id")) .ValueExpr("ItemCode").DisplayExpr("ItemText").Layout(Orientation.Horizontal).ID("dxRadioGroupPaymentTypeCode").Value(1));
                grItem.AddSimpleFor(i => i.BankDetailId).Editor(e => e.SelectBox().Placeholder(" ").DataSource(d => d.Mvc().Controller("BankDetail").LoadMode(DataSourceLoadMode.Raw).LoadAction("GetByBranchCode").LoadParams(new { BranchCode = Model.typePermission.Users.BranchCode }).LoadMode(DataSourceLoadMode.Raw).Key("Id")).ValueExpr("Id").DisplayExpr("BankName").ID("dxSelectBoxBankDetailId").Label("Ngân hàng").LabelMode(EditorLabelMode.Floating));
                grItem.AddSimpleFor(i => i.BankTranCode).Editor(e => e.TextBox().Width("40%")).Label(l => l.Text("Mã giao dịch")); 
            });
            item.AddEmpty(); 
            item.AddGroup().CssClass("BorderCss").Caption("Test 3").ColCountByScreen(c => c.Xs(1).Md(1).Sm(1).Lg(2)).ColSpan(2).Visible(true).Items(grItem => {
                grItem.AddSimpleFor(i => i.ReceipterTypeCode).Editor(e => e.SelectBox().DataSource(d => d.Mvc().Controller("Metadata").LoadAction("GetMetadataLoader").LoadMode(DataSourceLoadMode.Raw).LoadParams(new { grouptext = "RECEIPTER_TYPE" }).Key("Id")).Value("NV").ValueExpr("ItemCode").DisplayExpr("ItemText").Placeholder("").OnValueChanged("checkByReceipterTypeCode")); 
                grItem.AddSimpleFor(m => m.ReceipterName).Label(l => l.Text("Họ tên khách hàng")).Editor(e => e.TextBox().Disabled(true).ReadOnly(true).ID("dxSelectBoxKH").Placeholder(" ").Buttons(b => b.Add().Name("btnRemoveStaff").Location(TextEditorButtonLocation.After).Widget(w => w.Button().Text("Tìm kiếm").Disabled(false).Icon("find").OnClick("onClickBtnRemoveStaff").ID("btnRemoveStaff").Type(ButtonType.Success).StylingMode(ButtonStylingMode.Outlined))));

                grItem.AddSimpleFor(m => m.ReceipterName).Label(l => l.Text("Họ tên nhân viên")).Editor(e => e.SelectBox().OnSelectionChanged("onChooseStaff").DisplayExpr("Fullname").ValueExpr("Fullname").Disabled(false).ID("dxSelectBoxNvtd2").Placeholder(" ").DataSource(d => d.Mvc().Controller("BranchStaff").LoadAction("GetByBranchCode").LoadMode(DataSourceLoadMode.Processed).LoadParams(new { branchcode = new JS("GetBranchCode") }).Key("StaffCifCode")));
                grItem.AddSimpleFor(m => m.ReceipterCifCode).Editor(e => e.TextBox().ReadOnly(true));
                grItem.AddSimpleFor(m => m.ReceipterIdentifyTypeId).Editor(e => e.SelectBox().Placeholder(" ").DataSource(d => d.Mvc().Controller("Metadata").LoadAction("GetMetadataLoader").LoadMode(DataSourceLoadMode.Raw)
                .LoadParams(new { groupText = "IDENTIFYTYPE" }).Key("Id")).ValueExpr("ItemId").DisplayExpr("ItemText").ReadOnly(true));
                grItem.AddSimpleFor(m => m.ReceipterIdentifyNumber).Editor(e => e.TextBox().ReadOnly(true));
            });
            item.AddEmpty();
        })   
     )
</div>

原有CSS代码

.BorderCss {
    border: 1px solid !important;
    border-color: darkgreen !important;
    border-radius: 10px !important;
    padding: 5px !important;
    margin: 5px !important;
    box-sizing: border-box !important;
}

解决方法

通过调整CSS,利用Flex布局让同一行的分组自动匹配最高元素的高度,修改后的CSS如下:

/* 让表单行容器使用flex布局,强制子元素高度拉伸一致 */
.dx-form-row {
    display: flex;
    align-items: stretch;
}

/* 让分组项撑满父容器高度,并保持内部布局正常 */
.dx-form-item.BorderCss {
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* 保留原有样式并确保分组本身高度填满 */
.BorderCss {
    border: 1px solid darkgreen !important;
    border-radius: 10px !important;
    padding: 10px !important; /* 适当增加padding避免内容贴边框 */
    margin: 5px !important;
    box-sizing: border-box !important;
    height: 100%;
}

原理说明

  1. .dx-form-row设置为flex布局,align-items: stretch会让行内所有子元素自动拉伸到和行内最高元素相同的高度。
  2. .dx-form-item.BorderCss设置为flex列布局,确保分组内部的表单元素正常垂直排列,同时让分组本身高度撑满父容器。
  3. 调整原有.BorderCss的padding值,避免分组内的表单元素贴到边框上,同时添加height: 100%确保分组高度填满分配的空间。

内容的提问来源于stack exchange,提问作者Harry Phan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:27:03