0

UIElement の動作を変更するために「KeySet」を作成しようとしています。アイデアは、たとえば、特別な機能を作成することです。ユーザーが a を押しながら要素をクリックします。またはctrl+a。

これまでの私のアプローチでは、まず、考えられるすべての修飾子のコンテナーを作成します。単一のキーを許可するだけであれば、問題ありません。簡単な辞書を使用できます。

Dictionary<Keys, Action> _specialActionList
  • ディクショナリが空の場合は、デフォルト アクションを使用します。
  • エントリがある場合は、現在押されているキーに応じて使用するアクションを確認します

そして、私が貪欲でなければ、それで終わりです... もちろん、もっと欲しいです。複数のキーまたは修飾子を許可したい。そこで、辞書のキーとして使用できるラッパー クラスを作成しました。

より複雑なクラスを使用すると、明らかな問題があります。現在、2 つの異なるインスタンスが 2 つの異なるキーを作成するため、彼は私の関数を見つけることができません (理解するコードを参照してください。非常に明白です)。

今、私はこの投稿をチェックしました: GetHashCode override of object containing generic arrayは少し役に立ちました。

しかし、私の質問は、クラスの基本設計は大丈夫ですか。(リストの代わりに) 修飾子と通常のキーボード キーを格納するためにハッシュセットを使用する必要があります。もしそうなら、GetHashCode 関数はどのようになりますか?

書くコードがたくさんあることは知っていますが(退屈なハッシュ関数)、始めるにはいくつかのヒントで十分です。ここに試用版を投稿します...

ここまでのコードは、テストが明らかに失敗する...

        public class KeyModifierSet
    {
        private readonly List<Key> _keys = new List<Key>();
        private readonly List<ModifierKeys> _modifierKeys = new List<ModifierKeys>();

        private static readonly Dictionary<KeyModifierSet, Action> _testDict 
                          = new Dictionary<KeyModifierSet, Action>();

        public static void Test()
        {
            _testDict.Add(new KeyModifierSet(Key.A), () => Debug.WriteLine("nothing"));
            if (!_testDict.ContainsKey(new KeyModifierSet(Key.A))) throw new Exception("Not done yet, help :-)");
        }

        public KeyModifierSet(IEnumerable<Key> keys, IEnumerable<ModifierKeys> modifierKeys)
        {
            foreach (var key in keys)
                _keys.Add(key);

            foreach (var key in modifierKeys)
                _modifierKeys.Add(key);
        }

        public KeyModifierSet(Key key, ModifierKeys modifierKey)
        {
            _keys.Add(key);
            _modifierKeys.Add(modifierKey);
        }

        public KeyModifierSet(Key key)
        {
            _keys.Add(key);
        }
    }
4

2 に答える 2

0
 _testDict.Add(new KeyModifierSet(Key.A), () => Debug.WriteLine("nothing"));
 if (!_testDict.ContainsKey(new KeyModifierSet(Key.A))) throw new Exception("Not done yet, help :-)");

私があなたのコードを正しく理解していれば、Object.Equals および Object.GetHashCode メソッドのオーバーライドされたバージョンを使用して、_testDict Dictionary オブジェクトが等しいかどうかをテストしてください。私の知る限り、これらのメソッドをオーバーライドする独自のカスタム コレクション タイプを作成する必要があります。

于 2009-11-17T19:27:43.020 に答える
0

私自身の(少し複雑な)質問に答えるために、ここに解決策があります:

public class KeyModifierSet
{
    internal readonly HashSet<Key> Keys = new HashSet<Key>();
    internal readonly HashSet<ModifierKeys> MKeys = new HashSet<ModifierKeys>();

    public override int GetHashCode()
    {
        int hash = Keys.Count + MKeys.Count;
        foreach (var t in Keys)
        {
            hash *= 17;
            hash = hash + t.GetHashCode();
        }
        foreach (var t in MKeys)
        {
            hash *= 19;
            hash = hash + t.GetHashCode();
        }
        return hash;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as KeyModifierSet);
    }
    public bool Equals(KeyModifierSet other)
    {
        // Check for null
        if (ReferenceEquals(other, null))
            return false;

        // Check for same reference
        if (ReferenceEquals(this, other))
            return true;

        // Check for same Id and same Values
        return Keys.SetEquals(other.Keys) && MKeys.SetEquals(other.MKeys);
    }



    public KeyModifierSet(ModifierKeys mKey)
    {
        MKeys.Add(mKey);
    }
    public KeyModifierSet(Key key)
    {
        Keys.Add(key);
    }
    public KeyModifierSet(Key key, ModifierKeys mKey)
    {
        Keys.Add(key);
        MKeys.Add(mKey);
    }
    public KeyModifierSet Add(Key key)
    {
        Keys.Add(key);
        return this;
    }
    public KeyModifierSet Add(ModifierKeys key)
    {
        MKeys.Add(key);
        return this;
    }
}
于 2009-11-17T22:24:36.260 に答える