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

如何阻止行点击触发DetailRow显隐,仅按指定条件展示DetailRow

解决方案:仅通过行数据状态控制DataGrid DetailRow显示

核心问题分析

你遇到的问题根源在于:

  • 全局给所有列加PreventRowClick会完全阻断行级交互,导致DetailRowTrigger的评估逻辑无法被触发
  • 默认情况下DataGrid会把行点击作为DetailRow显示/隐藏的触发源,即使指定了DetailRowTrigger,行点击仍会覆盖自定义逻辑

具体修复步骤

1. 禁用行点击的默认DetailRow切换行为

在DataGrid组件上添加RowClickMode="DataGridRowClickMode.None",彻底取消行点击对DetailRow的控制:

<DataGrid TItem="VisitDocumentDTO"
          Data="@VisitDocuments"
          @ref="dataGridRef"
          RowStyling="@OnRowStyling"
          Responsive
          Resizable
          ResizeMode="TableResizeMode.Header"
          SortMode="DataGridSortMode.Single"
          ShowPager
          ShowPageSizes
          ShowGrouping
          CustomFilter="@OnCustomFilter"
          DetailRowStartsVisible="true"
          DetailRowTrigger="@ShowDetailRow"
          RowClickMode="DataGridRowClickMode.None" <!-- 新增该行 -->
          PagerPosition="DataGridPagerPosition.Bottom"
          PagerOptions="new(){ ButtonSize=Size.Small }">

2. 移除所有列的PreventRowClick属性

不需要再给每个列单独添加PreventRowClick,已经通过RowClickMode禁用了行点击的默认行为,保留列的正常交互能力。

3. 确保ShowDetailRow直接基于行数据状态判断

你的ShowDetailRow方法需要直接返回行的BillingStatus或预览状态,示例如下:

// 假设用字典跟踪各行的预览状态
private Dictionary<int, bool> _previewStates = new();

private bool ShowDetailRow(VisitDocumentDTO row)
{
    var isPreviewActive = _previewStates.TryGetValue(row.Id, out var state) && state;
    return row.BillingStatus || isPreviewActive;
}

4. 状态变更时强制重新评估DetailRow

在BillingStatus切换和预览按钮点击时,需要通知组件重新渲染,确保DetailRowTrigger被重新计算:

  • 修改Switch的CheckedChanged事件:
<Switch TValue="bool" 
        Checked="@context.BillingStatus" 
        CheckedChanged="@( (va) => {
            context.BillingStatus = va;
            StateHasChanged(); // 通知组件重新渲染
        })">
    Billable
</Switch>
  • 修改Preview按钮的点击事件:
private void TogglePreviewState(VisitDocumentDTO row)
{
    if (_previewStates.ContainsKey(row.Id))
        _previewStates[row.Id] = !_previewStates[row.Id];
    else
        _previewStates[row.Id] = true;
    
    StateHasChanged(); // 触发重新评估DetailRowTrigger
}

5. 可选:让DTO实现INotifyPropertyChanged(更优雅的状态通知)

如果你的VisitDocumentDTO实现了INotifyPropertyChanged,修改BillingStatus时会自动触发通知,无需手动调用StateHasChanged():

public class VisitDocumentDTO : INotifyPropertyChanged
{
    private bool _billingStatus;
    public bool BillingStatus
    {
        get => _billingStatus;
        set
        {
            if (_billingStatus != value)
            {
                _billingStatus = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // 其他属性...
}

最终效果

完成以上修改后,DetailRow的显示将完全由以下两个条件控制:

  • 行的BillingStatus为true
  • 该行的预览状态被激活
    行点击不会再影响DetailRow的显示,同时DetailRowTrigger会在状态变更时自动重新评估。

内容的提问来源于stack exchange,提问作者Jon Hogan-Doran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 03:44:54