如何在monoMac中处理NSTextField keyDown

时间:2016-01-07 23:22:59

标签: cocoa xamarin monomac

我尝试使用monoMac和Xamarin Studio处理NSTextField的keyDown事件。

我创建了一个NSTextFieldDelegate派生类,并将编辑器委托给该类的实例。但是,我只看到调用Changed方法,而不是DoCommandBySelector

class TextPathDelegate : NSTextFieldDelegate {
public override void Changed(NSNotification notification)
{
    Console.WriteLine("changed");
}
public override void DidChangeValue(string forKey)
{
    Console.WriteLine("didchange = {0}", forKey);
}
public override void WillChangeValue(string forKey)
{
    Console.WriteLine("willchange = {0}", forKey);
}

public override bool DoCommandBySelector(NSControl control, NSTextView textView, MonoMac.ObjCRuntime.Selector commandSelector)
{
    Console.WriteLine("DoCommandBySelector = {0}", commandSelector.ToString());
    return false;
}
}

知道我可能缺少什么吗?

修改-2: 我刚刚注意到,如果我使用箭头键并向上/向下翻页,则会调用DoCommandBySelector。仍然无法捕捉到keydown事件

修改-1: 我试图用Xamarin.mac创建一个小项目,只有2个编辑字段,带有派生编辑控件和委托。

这是代码

class TextPathDelegate : NSTextFieldDelegate {
    string Id { get; set; }
    public TextPathDelegate(string id) { Id = id; }
    public override void Changed(NSNotification notification)
    {
        Console.WriteLine(Id + "changed");
    }
    public override bool DoCommandBySelector(NSControl control, NSTextView textView, ObjCRuntime.Selector commandSelector)
    {
        Console.WriteLine(Id + "DoCommandBySelector = {0}", commandSelector.ToString());
        return false;
    }
    public override void EditingBegan(NSNotification notification)
    {
        Console.WriteLine(Id + "EditingBegan");
    }
    public override void EditingEnded(NSNotification notification)
    {
        Console.WriteLine(Id + "EditingEnded");
    }
}

[Register("MyNSTextField")]
class MyNSTextField : NSTextField {
    public MyNSTextField(IntPtr handle) : base(handle){}
    public override void KeyDown(NSEvent theEvent)
    {
        Console.WriteLine("KeyDown");
        base.KeyDown(theEvent);
    }
    public override void KeyUp(NSEvent theEvent)
    {
        Console.WriteLine("KeyUp");
        base.KeyUp(theEvent);
    }
}

和输出。没有调用keyDown或DoCommandBySelector。我必须遗漏一些非常基本的东西

1-EditingBegan
1-changed
KeyUp
1-changed
KeyUp
1-changed
KeyUp
1-EditingEnded
2-EditingBegan
2-changed
KeyUp
2-changed
KeyUp
2-changed
KeyUp

由于

1 个答案:

答案 0 :(得分:4)

文本编辑在Cocoa中真的与WPF不同;-) NSTextField和类似控件通常不处理实际编辑,因为使用了NSTextView字段编辑器...奇怪?对于Windows'取决于你如何看待它。 style控制是的,对于Cocoa来说,这是常态:

  

字段编辑器是由NSWindow维护的NSTextView。字段编辑器会替换窗口中的任何NSTextField或NSTextFieldCell以进行编辑。

半必读材料:Text Fields, Text Views, and the Field Editor

NSTextField没有响应KeyDown 字段编辑器处理它以及它提供的所有相关功能(单词完成,重音字母弹出窗口等等)。 。,从而创建自定义NSTextField并覆盖KeyDownKeyUp,只会调用KeyUp

    public override void KeyDown(NSEvent theEvent)
    {
        throw new Exception("NSTextField KeyDown never gets called");
    }

    public override void KeyUp(NSEvent theEvent)
    {
        Console.WriteLine("NSTextField KeyUp");
    }

因此NSTextFieldDelegate同样如此,你永远不会得到commandSelector的keydown / keyup ......你获得insertNewline:,{{1 },cancelOperation:等...

deleteBackward:

怎么办?

首先真的需要keydown吗?改变正常的Cocoa UIX不是常态,但如果你真的这样做,一种方法是使用自定义 public override void Changed(NSNotification notification) { Console.WriteLine("changed"); // after the field editor is done } public override bool DoCommandBySelector(NSControl control, NSTextView textView, Selector commandSelector) { Console.WriteLine("DoCommandBySelector = {0}", commandSelector.Name); return false; } 而不是NSTextView,并调用NSTextField覆盖:

KeyDown

如果您使用[Register("CustomTextView")] public class CustomTextView : NSTextView { public CustomTextView() : base() { Console.WriteLine("CustomTextView"); } public CustomTextView(IntPtr handle) : base(handle) { Console.WriteLine("CustomTextView IntPtr"); } [Export("initWithCoder:")] public CustomTextView(NSCoder coder) : base(coder) { Console.WriteLine("CustomTextView initWithCoder"); } public override void KeyDown(NSEvent theEvent) { Console.WriteLine("CustomTextView KeyDown"); } public override void KeyUp(NSEvent theEvent) { Console.WriteLine("CustomTextView KeyUp"); } } 进行界面设计,只需在C#中创建一个NSTextView子类,注册它,.xib将显示在Xcode中并用它来替换NSTextView与您的类。

根据您真正需要keyDown的内容,编辑开始/结束可能适用于您的.h

NSTextField

您也可以挂钩NSWindow的字段编辑器并监听所有this.EditingBegan += (object sender, EventArgs e) => { Console.WriteLine("EditingBegan"); }; this.EditingEnded += (object sender, EventArgs e) => { Console.WriteLine("EditingEnded"); }; ,过滤控件,只有在您感兴趣的控件时才会做出反应......