It gives an error "this key is not in the dictionary" when you press Q, W ... only the keys from D1 to D0 and backsapace work. Question: why gives an error, everything seems to be correct?

public enum Notes { Do1, Re1, Mi1, Fa1, Col1, La1, Si1, Do2, Re2, Mi2, Fa2, Col2, La2, Si2, Do3, Re3, Mi3, Fa3, Col3, La3, Si3, Do4, Re4, Mi4, Fa4, Col4, La4, Si4, Do5, Re5, Mi5, Fa5, Col5, La5, Si5, Do6, DoSharp1, ReSharp1, FaSharp1, ColSharp1, LaSharp1, DoSharp2, ReSharp2, FaSharp2, ColSharp2, LaSharp2, DoSharp3, ReSharp3, FaSharp3, ColSharp3, LaSharp3, DoSharp4, ReSharp4, FaSharp4, ColSharp4, LaSharp4, DoSharp5, ReSharp5, FaSharp5, ColSharp5, LaSharp5 } private Dictionary<Notes, MediaPlayer> sounds = new Dictionary<Notes, MediaPlayer>(); private Dictionary<Keys, bool> pressStates = new Dictionary<Keys, bool>(); private Dictionary<Keys, Notes> KeySounds = new Dictionary<Keys, Notes> { { Keys.D1, Notes.Do1 }, .... //для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π½ΠΎΡ‚Ρ‹ пСрСчислСния Notes Π·Π°Π΄Π°Π΅ΠΌ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹ .... { Keys.NumPad9, Notes.LaSharp5 } }; private void Form1_Load(object sender, EventArgs e) { //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ словари foreach (Notes s in Enum.GetValues(typeof(Notes)).Cast<Notes>()) { sounds.Add(s, new MediaPlayer()); pressStates.Add((Keys)s, false); } //НаполняСм ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π·Π²ΡƒΠΊΠ°ΠΌΠΈ sounds[Notes.Do1].Open(new Uri("s//_1.wav", UriKind.Relative)); .... //Для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π½ΠΎΡ‚Ρ‹ Π·Π°Π΄Π°Π΅ΠΌ Π·Π²ΡƒΠΊΠΎΠ²ΠΎΠΉ Ρ„Π°ΠΉΠ» .... sounds[Notes.LaSharp5].Open(new Uri("s//25.wav", UriKind.Relative)); } private void Form1_KeyDown(Object sender, KeyEventArgs e) { if (!KeySounds.ContainsKey(e.KeyCode)) return; if (!pressStates[e.KeyCode]) { pressStates[e.KeyCode] = true; PlaySound(KeySounds[e.KeyCode]); } } private void Form1_KeyUp(Object sender, KeyEventArgs e) { if (!KeySounds.ContainsKey(e.KeyCode)) return; if (pressStates[e.KeyCode]) { pressStates[e.KeyCode] = false; StopSound(KeySounds[e.KeyCode]); } } 
  • Well, and you see what kind of key in question. And is it really in the dictionary. - VladD
  • What is the type of Keys ? and how does it compare to the Notes type? - Igor
  • @Igor Keys is a standard WinForms msdn.microsoft.com/ru-ru/library/… listing - rdorn
  • @Igor keys are keyboard keys, in theory, the sound of a note is attached to a key - Valentin
  • It's simple, you incorrectly initialize the pressStates dictionary. It must be initialized in a separate cycle from the sounds , because now you have the wrong keys in it, but the casting is correct and the compiler does not say anything about it. - rdorn

1 answer 1

Error here:

 //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ словари foreach (Notes s in Enum.GetValues(typeof(Notes)).Cast<Notes>()) { sounds.Add(s, new MediaPlayer()); pressStates.Add((Keys)s, false); } 

Values ​​from the Notes enumeration can be cast to Keys values, because both enums are based on the int type. The compiler thinks that you understand what you are doing, since you use an explicit cast and it can be executed without errors. However, this in no way guarantees that the numerical codes of your notes will match the codes of the keys. which you want to use.

To fix it, divide it into two independent cycles, like this:

 //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π½ΠΎΡ‚ foreach (Notes s in Enum.GetValues(typeof(Notes)).Cast<Notes>()) { sounds.Add(s, new MediaPlayer()); } //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ состояний клавиш foreach (Keys k in KeySounds.Keys) { pressStates.Add(k, false); } 

or you can even in one cycle, but then like this:

 //Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ словари foreach (var s in KeySounds) { sounds.Add(s.Key, new MediaPlayer()); pressStates.Add(s.Value, false); } 
  • @Valentin I'm glad that helped. But still, next time try to shrink the code yourself to a readable size, leaving only the necessary one. It was a fairly simple case and rushed to my eyes from the second reading. in a more complicated case, such a sheet will be impossible to figure out - rdorn
  • well, I will consider for the future :) - Valentin