NSTableView:如何在右键单击时突出显示某个项目?

发布于 2024-12-07 16:25:56 字数 310 浏览 0 评论 0原文

我有一个 NSTableView,无需用户干预即可向其中添加项目。当用户返回到包含 NSTableView 的对话框并单击某个项目时,该项目将突出显示。但是,如果右键单击某个项目,则该项目不会突出显示。有没有办法突出显示右键单击的项目?

我目前有以下内容:

void Dialog::menuAction(ui::Menu::Item* item)
{ 
  // Highlight the item clicked
  [tableView row:item select:YES]
  ...
}

但这似乎不起作用。

I have an NSTableView, to which items are added without user intervention. When the user comes back to the dialog containing the NSTableView and clicks an item, that item is highlighted. However the item does not highlight if an item is right-clicked. Is there a way to highlight an item that is right-clicked?

I have the following currently:

void Dialog::menuAction(ui::Menu::Item* item)
{ 
  // Highlight the item clicked
  [tableView row:item select:YES]
  ...
}

But this doesn't seem to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Oo萌小芽oO 2024-12-14 16:25:56

我的解决方案似乎是迄今为止最干净的解决方案,它是对 NSTableView 进行子类化,并实现其 menuForEvent 消息。只需让您的表视图成为此视图的子类,您就会自动获得正确的行为:

@interface CustomTableView : NSTableView
@end

@implementation CustomTableView

- (NSMenu*) menuForEvent:(NSEvent*)event // override
{
    // Get to row at point
    NSInteger row = [self rowAtPoint:[self convertPoint:event.locationInWindow fromView:nil]];
    if (row >= 0) {
        // and check whether it is selected
        if (NOT [self isRowSelected:row]) {
            // No -> select that row
            [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
        }
    }
    return [super menuForEvent:event];
}

@end

应该与 NSOutlineView 类似地工作。

请注意代码如何决定何时突出显示该行。这与您在 Finder 中看到的行为非常相似,例如:

  • 如果右键单击现有选择,尤其是多个项目,它们将保持选中状态。
  • 如果在当前选择之外右键单击,新单击的行将成为新选择。

然而,这并不完美:只有当用户实际使用上下文菜单中的一项时,Finder 才会更改选择。如果用户取消弹出菜单,选择将不会改变。然而,我的代码在用户从弹出菜单中进行选择之前更改了选择。请随意改进这一点,并在这里分享。

My solution, which seems to be the cleanest shown here so far, is to subclass the NSTableView, and implement its menuForEvent message. Just make your table view a subclass of this and you'll get the correct behavior automatically:

@interface CustomTableView : NSTableView
@end

@implementation CustomTableView

- (NSMenu*) menuForEvent:(NSEvent*)event // override
{
    // Get to row at point
    NSInteger row = [self rowAtPoint:[self convertPoint:event.locationInWindow fromView:nil]];
    if (row >= 0) {
        // and check whether it is selected
        if (NOT [self isRowSelected:row]) {
            // No -> select that row
            [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
        }
    }
    return [super menuForEvent:event];
}

@end

Should work similarly with NSOutlineView.

Note how the code decides when to highlight the row. This mimicks closely the behavior that you can see in Finder, for instance:

  • If you right-click into an existing selection, especially if it's multiple items, they remain selected.
  • If you right-click outside the current selection, the newly clicked row becomes the new selection.

However, this is not perfect: The Finder only changes the selection once the user actually uses one of the items from the contextual menu. If the user cancels the popup menu, the selection won't change. My code, however, changes the selection before the user gets to choose from the popup menu. Feel free to improve on this, and share it here.

空袭的梦i 2024-12-14 16:25:56

这可能不完全是您想要的,但可能会有所帮助。我在获取右键单击以获取上下文菜单的行时遇到问题。我使用的是大纲视图,而不是表格视图,它位于主窗口中,而不是对话框中。

我有一个表达我的观点的出口。在处理菜单的对象中,我有以下方法:

- (void) setSelectionFromClick {
    NSInteger theClickedRow = [myOutlineView clickedRow];
    NSIndexSet *thisIndexSet = [NSIndexSet indexSetWithIndex:theClickedRow];
    [myOutlineView selectRowIndexes:thisIndexSet byExtendingSelection:NO];
}

我在每个菜单操作开始时调用此方法。

无论按下哪个按钮,都会设置单击的行。但选择仅在单击左按钮时自动更改。顺便说一句,这也适用于按住 Control 键单击。

This may not be exactly what you want, but it might help. I had the problem with getting the row that was right clicked to get a context menu. I'm using an outline view, not a table view, and it's in the main window, not a dialog.

I have an outlet to my outlne view. In an object that processes the menu, I have the following method:

- (void) setSelectionFromClick {
    NSInteger theClickedRow = [myOutlineView clickedRow];
    NSIndexSet *thisIndexSet = [NSIndexSet indexSetWithIndex:theClickedRow];
    [myOutlineView selectRowIndexes:thisIndexSet byExtendingSelection:NO];
}

I call this method at the start of every menu action.

The clicked row is set, whichever button is pushed. But selection only changes automatically when left button is clicked. By the way, this also works with control-click.

只是@Thomas Tempelmann 解决方案的快速版本。

public class TableViewWithRightClickSelect: NSTableView
{
    override open func menu(for event: NSEvent) -> NSMenu?
    {
        let row = self.row(at: self.convert(event.locationInWindow, from: nil))
        if row >= 0
        {
            self.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
        }
        
        return super.menu(for: event)
    }
}

just a swift version of @Thomas Tempelmann's solution.

public class TableViewWithRightClickSelect: NSTableView
{
    override open func menu(for event: NSEvent) -> NSMenu?
    {
        let row = self.row(at: self.convert(event.locationInWindow, from: nil))
        if row >= 0
        {
            self.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
        }
        
        return super.menu(for: event)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文