通过双击鼠标右键阻止编辑NSTextField



我使用的是MonoMac/C#,并且有一个NSOutlineView,其中一些项目是可编辑的。因此,如果选择一个项目,然后再次单击(缓慢双击),则该行的NSTextField将进入编辑模式。我的问题是,即使右键单击项目,也会发生这种情况。您甚至可以混合左键单击和右键单击以进入编辑模式。

这很烦人,因为有时你会选择一行,然后右键单击它,然后在上下文菜单出现一秒钟后,该行进入编辑模式。

是否有办法限制NSOutlineView或其中的NSTextFields,仅使用鼠标左键进入编辑模式(除了在选择行时按enter键)?

谢谢!

我使用的方法是覆盖"RightMouseDown"方法[1,2]。在尝试在NSOutlineView和NSTableCellView中这样做但没有成功之后,诀窍是向下到层次结构中的较低级别,进入NSTextField。事实证明,NSWindow对象使用SendEvent将事件直接分派到最接近鼠标事件[3]的视图,因此事件从最内部的视图进行到最外部的视图。

您可以在Xcode中的OutlineView中更改所需的NSTextField以使用此自定义类:

public partial class CustomTextField : NSTextField
{
    #region Constructors
    // Called when created from unmanaged code
    public CustomTextField (IntPtr handle) : base (handle)
    {
        Initialize ();
    }
    // Called when created directly from a XIB file
    [Export ("initWithCoder:")]
    public CustomTextField (NSCoder coder) : base (coder)
    {
        Initialize ();
    }
    // Shared initialization code
    void Initialize ()
    {
    }
    #endregion
    public override void RightMouseDown (NSEvent theEvent)
    {
        NextResponder.RightMouseDown (theEvent);
    }
}

由于"RightMouseDown"不会调用base.RightMouseDown(),因此NSTextField逻辑将完全忽略单击。调用NextResponder.RightMouseDown()允许事件在视图层次结构中向上渗透,这样它仍然可以触发上下文菜单。

[1]https://developer.apple.com/library/mac/documentation/cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/occ/instm/NSView/rightMouseDown:[2]https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/HandlingMouseEvents/HandlingMouseEvents.html[3]https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW21

@salgarcia的上述答案可以适用于Swift 3原生代码,如下所示:

import AppKit
class CustomTextField: NSTextField {
    override func rightMouseDown(with event: NSEvent) {
        // Right-clicking when the outline view row is already
        // selected won't cause the text field to go into edit 
        // mode. Still can be edited by pressing Return while the
        // row is selected, as long as the textfield it is set to 
        // 'Editable' (in the storyboard or programmatically):
        nextResponder?.rightMouseDown(with: event)
    }
}

最新更新