0

I am trying to create a "KeySet" to modify UIElement behaviour. The idea is to create a special function if, eg. the user clicks on an element while holding a. Or ctrl+a.

My approach so far, first lets create a container for all possible modifiers. If I would simply allow a single key, it would be no problem. I could use a simple Dictionary, with

Dictionary<Keys, Action> _specialActionList
  • If the dictionary is empty, use the default action.
  • If there are entries, check what action to use depending on current pressed keys

And if I wasn't greedy, that would be it... Now of course, I want more. I want to allow multiple keys or modifiers. So I created a wrapper class, wich can be used as Key to my dictionary.

There is an obvious problem when using a more complex class. Currently two different instances would create two different key, and thereby he would never find my function (see code to understand, really obvious)

Now I checked this post: GetHashCode override of object containing generic array which helped a little.

But my question is, is my basic design for the class ok. Should I use a hashset to store the modifier and normal keyboardkeys (instead of Lists). And If so, how would the GetHashCode function look like?

I know, its a lot of code to write (boring hash functions), some tips would be sufficient to get me started. Will post tryouts here...

And here comes the code so far, the Test obviously fails...

        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);
        }
    }
3
  • What programming language are you talking about? Commented Nov 17, 2009 at 19:10
  • You might want to add a tag indicating what language you're asking about. Commented Nov 17, 2009 at 19:10
  • And what the heck is your question!? Commented Nov 17, 2009 at 19:11

2 Answers 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 :-)");

If I understand your code correctly you would like to test your _testDict Dictionary object for equality using overrided versions of the Object.Equals and Object.GetHashCode methods. As far as I know you will need to create your own custom collection type that overrides these methods.

Sign up to request clarification or add additional context in comments.

Comments

0

To answer my own (slightly complicated posed) question, here is the solution:

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;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.