对某些KeyPress序列使用反应性扩展吗? [英] Using Reactive Extension for certain KeyPress sequences?

查看:52
本文介绍了对某些KeyPress序列使用反应性扩展吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手..或更确切地说,是从未使用过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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆