2010-08-17 12 views
2

Je suis nouveau .. ou plus précisément .. jamais utilisé RX donc je me demandais si je peux l'utiliser pour cette situation: Je veux ajouter une sorte de fonctionnalité Resharper Live Templates à mon application qui permet aux utilisateurs d'entrer de courtes séquences de caractères suivis d'un [Tab] et mon application remplacerait les caractères précédemment tapés avec l'ailleurs spécifié, texte intégral.Utilisation de Reactive Extension pour certaines séquences KeyPress?

Maintenant, j'ai une liste de tableaux de caractères, chacun d'eux représentant une séquence possible. Je veux une sorte de mots d'arrêt/clés qui cassent la chaîne (par exemple l'espace). J'ai un événement qui est levé sur chaque KeyPress dans mon application, maintenant (comment) puis-je utiliser RX pour observer cet événement et vérifier par rapport à cette liste si l'une des séquences a été remplie et enfin [Tab] pressé?

Répondre

3

Je ne sais pas si c'est trop tard, mais j'ai une réponse pour vous.

La méthode d'extension Rx que vous devez utiliser est BufferWithCount. Je suppose que vous savez comment transformer les événements de presse de touche en IObservable<char>.

vous donc donné avez une liste de séquences de caractères que vous voulez détecter puis effectuer une action que je suggère d'utiliser un Dictionary<string, Action> pour contenir ces données, comme ceci:

var matches = new Dictionary<string, Action>() 
{ 
    { "ba",() => Console.WriteLine("ba") }, 
    { "aba",() => Console.WriteLine("aba") }, 
    { "baa",() => Console.WriteLine("baa") }, 
    { "abc\t",() => Console.WriteLine("abc\\t") }, 
}; 

Alors, voici le Rx (et IEnumerable) requêtes nécessaires:

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]); 

donc finalement vous avez juste un IObservable<Action> que vous pouvez vous abonner à vous appeler juste le Action.

Si vous voulez tester que cela fonctionne utilisent le code suivant:

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(); 

Le résultat devrait être:

ba 
aba 
abc\t 
ba 
aba 
baa 
ba 
aba 
abc\t 
ba 

Amusez-vous!

+0

génial! Merci! –