我尝试使用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
由于
答案 0 :(得分:4)
文本编辑在Cocoa中真的与WPF不同;-) NSTextField和类似控件通常不处理实际编辑,因为使用了NSTextView字段编辑器...奇怪?对于Windows'取决于你如何看待它。 style控制是的,对于Cocoa来说,这是常态:
字段编辑器是由NSWindow维护的NSTextView。字段编辑器会替换窗口中的任何NSTextField或NSTextFieldCell以进行编辑。
半必读材料:Text Fields, Text Views, and the Field Editor
NSTextField
没有响应KeyDown
字段编辑器处理它以及它提供的所有相关功能(单词完成,重音字母弹出窗口等等)。 。,从而创建自定义NSTextField
并覆盖KeyDown
和KeyUp
,只会调用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");
};
,过滤控件,只有在您感兴趣的控件时才会做出反应......