I'm trying to handle the keyDown event for NSTextField using monoMac and Xamarin Studio.
I have created a NSTextFieldDelegate derived class and set the editors delegate to an instance of this class. However, I only see the Changed method being called, never the 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;
}
}
Any idea what I might be missing ?
Edit-2: I just noticed that DoCommandBySelector is being called if I use the arrow keys and page up/down. Still not able to catch the keydown event
Edit-1: I tried to make a small project with Xamarin.mac, just 2 edit fields, with a derived edit control and the delegate.
This is the code
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);
}
}
and the output. No call to keyDown or DoCommandBySelector. I must be missing something very basic
1-EditingBegan
1-changed
KeyUp
1-changed
KeyUp
1-changed
KeyUp
1-EditingEnded
2-EditingBegan
2-changed
KeyUp
2-changed
KeyUp
2-changed
KeyUp
Thanks
Text editing is in Cocoa is really different than WPF ;-) NSTextField and like controls normally do not deal with the actual editing as a NSTextView field editor is used... Strange? Depends upon on how you look at it, for Windows' style controls yes, for Cocoa it is the norm:
Semi-required Reading material : Text Fields, Text Views, and the Field Editor
NSTextFielddoes not respond to aKeyDownas the field editor handles it and all the related functions that it provides (word completion, accent letter popups, etc..., and thus creating a customNSTextFieldand overridingKeyDownandKeyUp, onlyKeyUpwill be called:Thus the same goes for
NSTextFieldDelegate, you will never get acommandSelectorfor keydown/keyup... you will getinsertNewline:,cancelOperation:,deleteBackward:, etc...What to do?
First do you really need keydown? Altering the normal Cocoa UIX is not the norm, but if you really do, one way is to use a custom
NSTextViewinstead of aNSTextFieldand theKeyDownoverride will be called:If you are using
.xibfor your interface design, just create a NSTextView subclass in C#, register it and the.hwill show up in Xcode and use it to replace the NSTextView with your class.Depending on what you really need keyDown for, maybe editing begin/end will work for your
NSTextField:You can also hook that NSWindow's field editor and listen for all
keyDown:, filter the controls and only react if it is a control that you are interested in...