事实证明这比我想象的要容易......
如果您可以单击列标题以显示选项(而不是直接在标题下方显示下拉菜单),那么可以使用ContextualMenu 组件和DetailsList 来实现。我通过调整官方文档中的可变行高示例来实现它:https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist/variablerowheights。
在您的 DetailsList 下添加一个 ContextualMenu:
<DetailsList
items={items}
columns={columns}
/>
{this.state.contextualMenuProps && <ContextualMenu {...this.state.contextualMenuProps} />}
在您的列定义中,设置 hasDropdown 操作,以便用户获得一个 UI 指示器,表明他们可以/应该单击标题,并调用 contextMenu 方法(注意我使用的是 onColumnContextMenu 和 onColumnClick所以无论他们是左键还是右键单击标题都没关系:
{
key: 'dept',
name: 'Department',
fieldName: 'dept',
minWidth: 125,
maxWidth: 200,
onColumnContextMenu: (column, ev) => {
this.onColumnContextMenu(column, ev);
},
onColumnClick: (ev, column) => {
this.onColumnContextMenu(column, ev);
},
columnActionsMode: ColumnActionsMode.hasDropdown,
}
当onColumnContextMenu 方法被调用时,我们需要构建将被ContextualMenu 组件使用的上下文菜单属性。还要注意dismissal方法,它清除了状态,所以菜单被隐藏了。
private onContextualMenuDismissed = (): void => {
this.setState({
contextualMenuProps: undefined,
});
}
private onColumnContextMenu = (column: IColumn, ev: React.MouseEvent<HTMLElement>): void => {
if (column.columnActionsMode !== ColumnActionsMode.disabled) {
this.setState({
contextualMenuProps: this.getContextualMenuProps(ev, column),
});
}
};
最后,在getContextualMenuProps 中,您需要确定哪些选项应该是供用户单击的。在此示例中,我只是提供排序选项(您需要添加一个 onClick 处理程序才能在用户单击项目时实际执行某些操作),但我将使用 column 来确定这些项目应该做什么实际上是并将过滤器绘制到项目集合中,以便用户可以选择一个进行过滤。
private getContextualMenuProps = (ev: React.MouseEvent<HTMLElement>, column: IColumn): IContextualMenuProps => {
const items: IContextualMenuItem[] = [
{
key: 'aToZ',
name: 'A to Z',
iconProps: { iconName: 'SortUp' },
canCheck: true,
checked: column.isSorted && !column.isSortedDescending,
},
{
key: 'zToA',
name: 'Z to A',
iconProps: { iconName: 'SortDown' },
canCheck: true,
checked: column.isSorted && column.isSortedDescending,
}
];
return {
items: items,
target: ev.currentTarget as HTMLElement,
directionalHint: DirectionalHint.bottomLeftEdge,
gapSpace: 10,
isBeakVisible: true,
onDismiss: this.onContextualMenuDismissed,
}
}
注意ContextualMenuProps 对象上的target,它告诉ContextualMenu 将自己锁定在哪里(在本例中,是您单击以实例化菜单的列标题。