我正在尝试使用NSTextField
实现自动完成功能,用户将在其中输入一些字符串,并且将从显示在文本字段下的API提取建议。 (可选)在文本字段内显示进度指示器。到目前为止,我已经在Xcode IB中设计了UI,并钩住了事件以获取文本更改事件。
public class UserTextFieldDelegate: NSTextFieldDelegate
{
public NSTextField Username { get; set; }
public UserTextFieldDelegate()
{
}
public UserTextFieldDelegate(NSTextField username)
{
this.Username = username;
}
public override void Changed(NSNotification notification)
{
Console.WriteLine(Username.StringValue);
}
}
API将返回我需要与自动完成列表的数据源绑定的对象列表。
如何在Xamarin.Mac中实现此目标?
最佳答案
在NSTextField.Changed
中,保存NSNotification参数中的NSTextView
并调用Rest API:
NSString NSFieldEditor = new NSString("NSFieldEditor");
NSTextView editor;
[Export("controlTextDidChange:")]
public void Changed(NSNotification notification)
{
editor = editor ?? notification.UserInfo.ObjectForKey(NSFieldEditor) as NSTextView;
SomeRestCall(nsTextField.StringValue);
}
现在,使用Rest方法,通过后台队列调用实际的Rest api,并保存/缓冲字符串数组中返回的完成词,然后对通过
NSTextView.Complete
方法保存的NSTextView实例变量调用Changed
:string[] completionWords = { };
void SomeRestCall(string search)
{
if (editor != null)
{
DispatchQueue.GetGlobalQueue(DispatchQueuePriority.Background).DispatchAsync(() =>
{
if (string.IsNullOrWhiteSpace(search))
completionWords = new string[] { };
else
// Fake a REST call...
completionWords = (new string[] { "sushi", "stack", "over", "flow" })
.Where((word) => word.StartsWith(search, StringComparison.CurrentCulture)).ToArray();
if (editor != null)
DispatchQueue.MainQueue.DispatchAsync(() => { editor?.Complete(null); });
});
}
}
在
INSTextFieldDelegate
的实现中,添加GetCompletions
协议并返回在上一步中保存的完成字:[Export("control:textView:completions:forPartialWordRange:indexOfSelectedItem:")]
public string[] GetCompletions(NSControl control, NSTextView textView, string[] words, NSRange charRange, ref nint index)
{
requestor = null;
return completionWords;
`}