我是新手......或者更准确地说......从未使用过 RX 所以我想知道我是否可以将它用于这种情况:我想在我的应用程序中添加一种 Resharper Live Templates 功能,允许用户输入短序列后跟 [Tab] 的字符,我的应用程序会将之前键入的字符替换为其他地方指定的全文。
现在我有了一个字符数组列表,每个字符数组代表一个可能的序列。我想要某种中断链的停用词/键(例如空格)。 我在我的应用程序中的每个 KeyPress 上都有一个事件,现在(如何)我可以使用 RX 来观察这个事件并检查上述列表中的一个序列是否已经完成并最终按下 [Tab]?
最佳答案
我不知道现在是否为时已晚,但我有一个答案要告诉你。
你需要使用的Rx扩展方法是BufferWithCount
.
我假设您知道如何将按键事件转换为 IObservable<char>
.
假设您有一个要检测的字符序列列表,然后执行我建议使用 Dictionary<string, Action>
的操作保存这些数据,像这样:
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
)查询:
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
.
如果您想测试它是否有效,请使用以下代码:
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
尽情享受吧!
关于c# - 对某些 KeyPress 序列使用 Reactive Extension?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3501073/