如何让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
相关产品推荐
相关产品推荐

