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

がりらぼ

WindowsRuntimeの応援ブログ

Windowsストアアプリでキーバインドを可能にするライブラリKeyBindManager

この記事には最新バージョンがあります!!

KeyBindManager version2.0 - がりらぼ


Windowsデベロッパーセンターみてても、WPFにあったようなキーバインドはありません。
キーバインドは死んだ!もういない!

ってわけにもいかないので無理やりキーバインドさせるライブラリを作ってみました。
「KeyBindManager」という名前でNugetで公開しています。
検索検索ゥ!!
f:id:garicchi:20140212095013p:plain

クラスはKeyBind、KeyBinder、KeyManagerの3つ。
KeyBindクラスは修飾キー、メインキー、キーが押された時のコールバックメソッドを持ちます。
KeyBinderはKeyBindのコレクションを持ちます。
KeyManagerはUIElementのKeyDownとKeyUpイベントをKeyBindと関連付けることができます。

使い方

//UIElementとKeyBinderを関連付ける
KeyManager listViewKeyManager;

//キーバインドのコレクションを持つ
KeyBinder keyBinder;

keyBinder = new KeyBinder();

//単一キーのバインド、押された時コールバックが呼ばれる
keyBinder.KeyBindList.Add(new KeyBind(VirtualKey.F, (bind) =>
{
    listView.Items.Add(bind.MainKey.ToString() + "キーが押されています");
}));

//2キーのバインド、2キーが同時におされたときに呼ばれる
keyBinder.KeyBindList.Add(new KeyBind(VirtualKey.Control, VirtualKey.Enter, (bind) =>
{
    listView.Items.Add(bind.OptionKey.ToString() + "キーと" + bind.MainKey.ToString() + "キーが押されています");
}));

//UIElementコントロールとKeyBinderを結びつける
//このインスタンスが保持されている限りキーイベントを取得できる
listViewKeyManager = new KeyManager(listView, keyBinder);

コンストラクタでこんな感じなことをするとキーバインドができます。
ただ、UIElementがKeyDownイベントを取得できる状態でないとキーバインドできないのでGridとかはキーバインドするのが難しいと思います。(TextBoxならなんなくできます)

AcceptReturnを許可したTextBoxでEnterを含めたキーバインドを行う

TextBoxのAcceptReturnを許可するとEnterのKeyDownイベントを取得できません。
そこで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)
        {
            bind.CheckKeyDown(e.Key);
        }
    }
}

こいつをさっきと同じように使えばEnterもバインドできるTextBoxの完成となります。

バグ

このライブラリには致命的バグがあります。
Ctrl+(キー)と(キー)の区別ができない!!!
ちょっとめんどくさいバグを残してしまいましたが設計ミスなので治すのがめんどくさくなりました。ゆるして