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

如何让MudSimpleTable中按钮触发的MudPopover显示在按钮附近

问题

使用MudSimpleTable时,每行按钮触发的MudPopover没有显示在按钮附近,而是出现在页面顶部,如何修正?

示例代码:

<MudSimpleTable Style="overflow-x: auto;">
 <thead>
 <tr>
 @foreach (var h in headings)
 {
 <th>@h</th>
 }
 </tr>
 </thead>
 <tbody>
 @foreach (var row in rows)
 {       
  <tr>
  @foreach (var x in row.Split())
  {
  <td>@x
  <MudIconButton  OnClick="()=>ToggleOpen(x)" Icon="@Icons.Material.Filled.Fullscreen" Color="@Color.Primary" ToggledIcon="@Icons.Material.Filled.FullscreenExit" ToggledColor="@Color.Secondary" />
  </td>
  }
  </tr>
  }
 </tbody>
 </MudSimpleTable>
 <MudPopover Open="@_isOpen" Fixed="true" Class="px-4 pt-4" >
 <div class="d-flex flex-column">
 <MudText>@canonicalvalue</MudText>
 <MudButton OnClick="ToggleOpen" Class="ml-auto mr-n3 mb-1" Color="Color.Error">Close</MudButton>
 </div>
 </MudPopover> 
解决方案

问题核心是当前的MudPopover未关联到触发按钮,且设置了Fixed="true"导致固定定位到页面顶部。以下是两种可行的修复方式:

方式一:将Popover嵌入按钮所在容器并绑定目标元素

把MudPopover放到按钮所在的<td>内部,通过Target属性关联触发按钮,同时移除Fixed="true":

<MudSimpleTable Style="overflow-x: auto;">
    <thead>
        <tr>
            @foreach (var h in headings)
            {
                <th>@h</th>
            }
        </tr>
    </thead>
    <tbody>
        @foreach (var row in rows)
        {       
            <tr>
                @foreach (var x in row.Split())
                {
                    <td>
                        @x
                        <MudIconButton @ref="@_currentButton" OnClick="()=>ToggleOpen(x)" 
                                      Icon="@Icons.Material.Filled.Fullscreen" Color="@Color.Primary" 
                                      ToggledIcon="@Icons.Material.Filled.FullscreenExit" ToggledColor="@Color.Secondary" />
                        <!-- 将Popover放入td内,绑定目标按钮 -->
                        <MudPopover Open="@_isOpen" Target="()=>_currentButton" Class="px-4 pt-4">
                            <div class="d-flex flex-column">
                                <MudText>@canonicalvalue</MudText>
                                <MudButton OnClick="ToggleOpen" Class="ml-auto mr-n3 mb-1" Color="Color.Error">Close</MudButton>
                            </div>
                        </MudPopover>
                    </td>
                }
            </tr>
        }
    </tbody>
</MudSimpleTable>

对应的@code块补充按钮引用和逻辑:

private MudIconButton _currentButton;
private bool _isOpen;
private string canonicalvalue;

private void ToggleOpen(string value = null)
{
    if (!string.IsNullOrEmpty(value))
    {
        canonicalvalue = value;
    }
    _isOpen = !_isOpen;
}

方式二:使用PopoverService动态创建弹窗(适合多弹窗场景)

通过注入IPopoverService来动态管理弹窗,无需在页面中预先定义MudPopover:

<MudSimpleTable Style="overflow-x: auto;">
    <thead>
        <tr>
            @foreach (var h in headings)
            {
                <th>@h</th>
            }
        </tr>
    </thead>
    <tbody>
        @foreach (var row in rows)
        {       
            <tr>
                @foreach (var x in row.Split())
                {
                    <td>
                        @x
                        <MudIconButton @ref="@_currentButton" OnClick="()=>ShowPopover(x)" 
                                      Icon="@Icons.Material.Filled.Fullscreen" Color="@Color.Primary" 
                                      ToggledIcon="@Icons.Material.Filled.FullscreenExit" ToggledColor="@Color.Secondary" />
                    </td>
                }
            </tr>
        }
    </tbody>
</MudSimpleTable>
<!-- 必须添加PopoverProvider -->
<MudPopoverProvider />

@code块逻辑:

[Inject] private IPopoverService PopoverService { get; set; }
private MudIconButton _currentButton;
private Guid? _activePopoverId;

private void ShowPopover(string value)
{
    // 关闭已打开的弹窗
    if (_activePopoverId != null)
    {
        PopoverService.Close(_activePopoverId.Value);
        _activePopoverId = null;
        return;
    }

    // 创建新弹窗并绑定目标按钮
    _activePopoverId = PopoverService.Show(new PopoverOptions
    {
        Target = () => _currentButton,
        Class = "px-4 pt-4",
        Content = _ => 
        {
            return new MudElement
            {
                ChildContent = builder =>
                {
                    builder.OpenComponent<MudText>(0);
                    builder.AddAttribute(1, nameof(MudText.Text), value);
                    builder.CloseComponent();
                    builder.OpenComponent<MudButton>(2);
                    builder.AddAttribute(3, nameof(MudButton.OnClick), EventCallback.Factory.Create(this, () => PopoverService.Close(_activePopoverId.Value)));
                    builder.AddAttribute(4, nameof(MudButton.Color), Color.Error);
                    builder.AddAttribute(5, nameof(MudButton.Class), "ml-auto mr-n3 mb-1");
                    builder.AddAttribute(6, nameof(MudButton.ChildContent), (RenderFragment)(b => b.AddContent(0, "Close")));
                    builder.CloseComponent();
                }
            };
        }
    });
}

关键注意事项

  • 移除Fixed="true":该属性会让弹窗脱离正常文档流,无法跟随目标元素定位
  • 必须设置Target:指定弹窗关联的触发元素,MudBlazor会自动计算弹窗相对于目标的位置

内容的提问来源于stack exchange,提问作者Sapri s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:35:59