This is another very beautiful use of Rx. The following program demonstrates how the app starts listening to commands when user presses space bar twice within the timespan of 1.5 seconds. To tell the user that I am listening, it can kick of a glowing animation, here I have just made a thick border visible. Now if the user stops and types nothing, the app stops listening. If the user continues to type, the next token entered is matched by any of the app commands and the subsequent token is then the command parameter. Line of business applications really become a lot more comforting to work on with such commanding flexibility:-
Enjoy Rx-ing!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
TaskScheduler _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
List<string> commandList = new List<string> { "(DS)", "(DEAL)", "(DEALSEARCH)", "(DEALVIEW)", "(DEALFILTER)",
"(SS)", "(SHIP)", "(PS)", "(PAR)" };
string commandRegex = string.Format("^{0}",string.Join("|",commandList));
InitializeComponent();
string command = string.Empty;
var textChangedEvent = Observable.FromEventPattern(this, "KeyUp");
textChangedEvent.Subscribe(
e =>
{
var key = ((KeyEventArgs)e.EventArgs).Key.ToString();
command += key;
}
);
textChangedEvent.Subscribe(
t =>
{
if (Regex.IsMatch(command, "^(Space)(Space)+"))
{
Task.Factory.StartNew(() => { border.BorderThickness = new Thickness(5); }, System.Threading.CancellationToken.None,
TaskCreationOptions.None, _uiScheduler
);
}
}
);
textChangedEvent.Throttle(TimeSpan.FromMilliseconds(1500)).Subscribe(
t =>
{
if (Regex.IsMatch(command, "^(Space)(Space)+"))
{
command = Regex.Replace(command, "^(Space)*", "");
if(Regex.IsMatch(command,commandRegex))
ExecuteCommand(Regex.Match(command, commandRegex).Value, Regex.Replace(command, commandRegex, "").Replace("Space", ""));
Task.Factory.StartNew(() => { border.BorderThickness = new Thickness(0); }, System.Threading.CancellationToken.None,
TaskCreationOptions.None, _uiScheduler
);
}
command = "";
}
);
}
private void ExecuteCommand(string command, string parameter)
{
MessageBox.Show(string.Format("Command={0} Parameter={1}", command, parameter));
}
}
}
Enjoy Rx-ing!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
TaskScheduler _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
List<string> commandList = new List<string> { "(DS)", "(DEAL)", "(DEALSEARCH)", "(DEALVIEW)", "(DEALFILTER)",
"(SS)", "(SHIP)", "(PS)", "(PAR)" };
string commandRegex = string.Format("^{0}",string.Join("|",commandList));
InitializeComponent();
string command = string.Empty;
var textChangedEvent = Observable.FromEventPattern(this, "KeyUp");
textChangedEvent.Subscribe(
e =>
{
var key = ((KeyEventArgs)e.EventArgs).Key.ToString();
command += key;
}
);
textChangedEvent.Subscribe(
t =>
{
if (Regex.IsMatch(command, "^(Space)(Space)+"))
{
Task.Factory.StartNew(() => { border.BorderThickness = new Thickness(5); }, System.Threading.CancellationToken.None,
TaskCreationOptions.None, _uiScheduler
);
}
}
);
textChangedEvent.Throttle(TimeSpan.FromMilliseconds(1500)).Subscribe(
t =>
{
if (Regex.IsMatch(command, "^(Space)(Space)+"))
{
command = Regex.Replace(command, "^(Space)*", "");
if(Regex.IsMatch(command,commandRegex))
ExecuteCommand(Regex.Match(command, commandRegex).Value, Regex.Replace(command, commandRegex, "").Replace("Space", ""));
Task.Factory.StartNew(() => { border.BorderThickness = new Thickness(0); }, System.Threading.CancellationToken.None,
TaskCreationOptions.None, _uiScheduler
);
}
command = "";
}
);
}
private void ExecuteCommand(string command, string parameter)
{
MessageBox.Show(string.Format("Command={0} Parameter={1}", command, parameter));
}
}
}