对某些KeyPress序列使用反应性扩展吗? [英] Using Reactive Extension for certain KeyPress sequences?
问题描述
我是新手..或更确切地说,是从未使用过RX,所以我想知道是否可以在这种情况下使用它:我想在我的应用程序中添加某种Resharper Live Templates功能,允许用户输入短序列字符后跟一个[Tab],我的应用程序将用其他指定的全文替换以前键入的字符.
I am new .. or more precisely.. never used RX so I was wondering whether I can use it for this situation: I want to add a sort of Resharper Live Templates functionality to my app that allows users to enter short sequences of characters followed by a [Tab] and my app would replace the previously typed characters with the elsewhere specified, full text.
现在我有一个字符数组列表,每个字符数组代表一个可能的序列.我想要某种中断链的停用词/键(例如空格).我在应用程序中的每个KeyPress上都引发了一个事件,现在(如何)我可以如何使用RX来观察此事件并对照上述列表检查是否已满足序列之一,并最终按下了[Tab]?/p>
Now I have a list of character arrays, each of them representing one possible sequence. I want some sort of stopwords/-keys that break the chain (e.g. space). I have an event that is raised on each KeyPress in my application, now (how) can I use RX to observe this event and check against that aforementioned list whether one of the sequences has been fulfilled and finally [Tab] has been pressed?
推荐答案
我不知道是否为时已晚,但是我有一个答案.
I don't know if it's too late, but I have an answer for you.
您需要使用的Rx扩展方法是 BufferWithCount
.
The Rx extension method you need to use is BufferWithCount
.
我假设您知道如何将按键事件转换为 IObservable< char>
.
I'll assume you know how to turn key press events into an IObservable<char>
.
因此,给定您要检测的字符序列列表,然后执行操作,我建议使用 Dictionary< string,Action>
来保存此数据,如下所示:
So given you have a list of character sequences that you want to detect and then perform an action I suggest using a Dictionary<string, Action>
to hold this data, like so:
var matches = new Dictionary<string, Action>()
{
{ "ba", () => Console.WriteLine("ba") },
{ "aba", () => Console.WriteLine("aba") },
{ "baa", () => Console.WriteLine("baa") },
{ "abc\t", () => Console.WriteLine("abc\\t") },
};
因此这是所需的Rx(和 IEnumerable
)查询:
So here's the Rx (and IEnumerable
) queries required:
int max =
matches
.Select(m => m.Key.Length)
.Max();
IObservable<string> chords =
Enumerable
.Range(2, max - 1)
.Select(n => keys
.BufferWithCount(n, 1)
.Select(cs => new string(cs.ToArray())))
.Merge();
IObservable<Action> actions =
chords
.Where(s => matches.ContainsKey(s))
.Select(s => matches[s]);
因此,最后您只有一个可以订阅的 IObservable< Action>
,并且只需调用 Action
.
So finally you just have an IObservable<Action>
that you can subscribe to and you just invoke the Action
.
如果要测试该方法是否有效,请使用以下代码:
If you want to test out that this works use the following code:
IConnectableObservable<char> keys = "ababc\tdabaababc\tebad"
.ToObservable()
.Publish();
//`.Publish()` makes a cold observable become hot,
// but you must call `Connect()` to start producing values.
//insert above `matches` definition here.
//insert above queries here.
actions.Subscribe(a => a());
keys.Connect();
结果应为:
ba
aba
abc\t
ba
aba
baa
ba
aba
abc\t
ba
享受!
这篇关于对某些KeyPress序列使用反应性扩展吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!