読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

KeyBindManager version2.0

自作ソフト WindowsRuntime C#

さっき公開したばかりのWindowsストアアプリでKeyBindを可能にするライブラリKeyBindManagerですが、Version1公開してからわずか4時間ぐらいで早速Version2に更新しました。ラピッドリリース
しかも超大幅更新

変更点

まず、前回はKeyBindクラスとして、
[バインドしたいキー1],[バインドしたいキー2],[キーが押された時の命令(Action)]
の3つがありました。
しかし、キー2つとActionを結合させると結合力が強すぎるというかActionがキーと一緒のクラスにある時点でかなり縛られるので疎結合にすることにしました。

KeyBindは
[バインドしたいキー1],[バインドしたいキー2],[命令ID]
の3つにしました。
KeyManagerの方で、Dictionary型の
[命令ID],[命令(Action)]
の2つを定義しています。

KeyBindとKeyManagerとの間にString型の命令IDを入れることで疎結合にしました。
f:id:garicchi:20140212131445p:plain

まあ命令をString型にすることでキーバインド設定をXMLとして保存したとしても復元が非常に多分楽になるはず...

使い方

基本的にはKeyBindにキーを、KeyManagerに命令を、お互いに同一のIDを用いることで結合という感じにしています。
Nugetで「KeyBindManager」で検索

private KeyManager keyManager { get; set; }
private KeyBinder keyBinder { get; set; }


keyBinder = new KeyBinder();
//キーバインドを作成
keyBinder.KeyBindList.Add(new KeyBind(VirtualKey.Control, VirtualKey.Enter,"PostTweet"));

//キー検知したいUIとキーバインドを結合
keyManager = new TweetKeyManager(textPost,keyBinder);

//同一IDがある場合のみActionを実行
keyManager.CommandList.Add("PostTweet",async(bind)=>{
    string str = textPost.Text;
    viewModel.TwitterTimeLineModel.PostText = str;
    ChangePostText(string.Empty);
    
    await PostTextAsync(str); 
});

AcceptReturn可能なTextBox

これは前回と同様ですがBindManagerがちょっとチガウ
とりあえずTextBoxを継承

    public class TweetTextBox:TextBox
    {
        public event KeyEventHandler EnterDown;
        public TweetTextBox()
        {
            this.AcceptsReturn = true;
        }
        protected override void OnKeyDown(KeyRoutedEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.Key == VirtualKey.Enter)
            {
                EnterDown(this, e);
            }

        }
    }

KeyManagerを変更

public class TweetKeyManager : KeyManager
{
    public TweetKeyManager(TweetTextBox element, KeyBinder binder)
        : base(element, binder)
    {
        element.EnterDown += element_EnterDown;
    }

    private void element_EnterDown(object s, KeyRoutedEventArgs e)
    {
        foreach (KeyBind bind in KeyBinder.KeyBindList)
        {
            if (bind.CheckKeyDown(e.Key))
            {
                if (CommandList.ContainsKey(bind.CommandCode))
                {
                    CommandList[bind.CommandCode](bind);
                }
            }
        }
    }
}


でおんなじ感じにすればいけるはず


むっつ氏もなんかつくってるのでこれはKeyBind戦争が起こりかねない....