electron 如何从上下文茶杯中获取TreeView中当前选定得项?

2w2cym1i  于 2022-12-08  发布在  Electron
关注(0)|答案(2)|浏览(198)

我需要在我的TreeWiew中添加一个上下文菜单。我用这个mui.com's Menu成功地做到了这一点,但我不知道如何在树中获取用户右键单击打开上下文菜单的选定项。例如,假设用户打开上下文菜单并单击“复制消息”,我想知道用户选择了哪个节点(Calendar,OSS,index.js等)并执行正确的操作。我试过在TreeView中查找onNodeSelect之类的内容,但当您在该项上打开上下文菜单时,它没有触发。当前代码如下所示:

export default function FileSystemNavigator() {
  const [contextMenu, setContextMenu] = React.useState<{
    mouseX: number;
    mouseY: number;
  } | null>(null);

  const handleContextMenu = (event: React.MouseEvent) => {
    event.preventDefault();
    setContextMenu(
      contextMenu === null
        ? {
            mouseX: event.clientX + 2,
            mouseY: event.clientY - 6
          }
        : // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
          // Other native context menus might behave different.
          // With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
          null
    );
  };

  const handleClose = () => {
    setContextMenu(null);
  };

  return (
    <div onContextMenu={handleContextMenu} style={{ cursor: "context-menu" }}>
      <TreeView
        aria-label="file system navigator"
        defaultCollapseIcon={<ExpandMoreIcon />}
        defaultExpandIcon={<ChevronRightIcon />}
        sx={{ height: 240, flexGrow: 1, maxWidth: 400, overflowY: "auto" }}
      >
        <TreeItem nodeId="1" label="Applications">
          <TreeItem nodeId="2" label="Calendar" />
        </TreeItem>
        <TreeItem nodeId="5" label="Documents">
          <TreeItem nodeId="10" label="OSS" />
          <TreeItem nodeId="6" label="MUI">
            <TreeItem nodeId="8" label="index.js" />
          </TreeItem>
        </TreeItem>
      </TreeView>
      <Menu
        open={contextMenu !== null}
        onClose={handleClose}
        anchorReference="anchorPosition"
        anchorPosition={
          contextMenu !== null
            ? { top: contextMenu.mouseY, left: contextMenu.mouseX }
            : undefined
        }
      >
        <MenuItem onClick={handleClose}>Copy Ctrl+C</MenuItem>
        <MenuItem onClick={handleClose}>Delete</MenuItem>
        <MenuItem onClick={handleClose}>Move</MenuItem>
        <MenuItem onClick={handleClose}>Email</MenuItem>
      </Menu>
    </div>
  );
}

Here's实时代码示例

monwx1rj

monwx1rj1#

你可以通过一个小的黑客来实现这个目标--在打开上下文菜单时触发click event。这将触发TreeView组件的onNodeSelect回调。

export default function FileSystemNavigator() {
  // ...

  const [selectedNodeId, setSelectedNodeId] = React.useState<string | null>(
    null
  );

  const handleContextMenu = (event: React.MouseEvent) => {
    event.target.click();

    event.preventDefault();
    // ...
  };

  const handleNodeSelect = (event, nodeId) => {
    setSelectedNodeId(nodeId);
  };

  return (
    <div onContextMenu={handleContextMenu} style={{ cursor: "context-menu" }}>
      <TreeView
        {/* ... */}
        onNodeSelect={handleNodeSelect}
      ></TreeView>
      <Menu>
        {/* ... */}
        <MenuItem onClick={handleClose}>Delete node {selectedNodeId}</MenuItem>
        {/* ... */}
      </Menu>
    </div>
  );
}

它将产生以下结果:x1c 0d1x

c6ubokkw

c6ubokkw2#

由于只有一个上下文菜单根据右键单击位置动态计算位置,因此应使用onContextMenu处理程序中事件来查找右键单击树项例如,右键单击'Application'节点时,在你的handleContextMenuevent.target里面你会发现<div class="MuiTreeItem-label">Applications</div>-你只需要把这段信息存储在内部状态中,然后在MenuItem单击处理程序中重用相同状态。我假设您可以将一些自定义属性或id附加到TreeItem,这样您就可以进一步简化所单击树项的解析器(以避免检查HTML div的innerText)。

相关问题