2012-04-03 32 views
6

Tengo un cuadro combinado que se completa con la enumeración Keys (winforms).Nombres de teclas bonitas en C# (Formularios)

El problema es que los nombres de las teclas no son muy claros para los usuarios inexpertos. Por ejemplo, el usuario promedio puede no saber qué significa 'OemPipe' o 'HanjaMode'. Entonces, ¿cómo puedo resolver este problema y tener algunos nombres de teclas mejores?

Estoy pensando en hacer un diccionario con las teclas y sus nombres, pero ocupar el diccionario me lleva mucho tiempo.

+0

Esto es lo que se refiere a – Sandeep

+0

@JustinNiessner Keys es una enumeración de formularios de Windows (System.Windows.Forms.Keys). – Tibi

+0

Tendrás que crear una descripción para cada valor, que es la parte que consume mucho tiempo. No importa cómo los guardas. –

Respuesta

7

Elabore un archivo de recursos que asigne nombres clave a una cadena comprensible para el usuario. Si el archivo de recursos no tiene un valor para una clave en particular, simplemente vaya con el nombre de clave (como lo está haciendo ahora), de modo que solo tiene que definir los que son difíciles de entender, y usted no tengo que hacerlos todos por adelantado

Esto también le permite localizar a diferentes idiomas, si lo desea.

EDITAR: Ejemplo de código agregado. Suposición es que usted tiene un archivo de recursos denominado "KeyNames.resx"

foreach (var key in Enum.GetValues(typeof(Keys))) 
{ 
    var keyName = KeyNames.ResourceManager.GetString(key.ToString()); 
    if (keyName == null) 
     keyName = key.ToString(); 

    comboBox1.Items.Add(keyName); 
} 
+1

En general, esta es probablemente una mejor solución que codificar los valores fáciles de usar, incluso si no necesita localizar. – jnylen

+0

Esta parece ser la mejor solución. – Tibi

0

No hay forma de escribir el código usted mismo. He aquí un enfoque que podría utilizar que es probablemente cerca del mínimo esfuerzo requerido, sin embargo:

string GetBaseKeyDescription(Keys k) { 
    switch (k & ~Keys.Modifiers) { 
     case Keys.OemPipe: 
      return "Pipe |"; 
     case Keys.OemPeriod: 
      return "Dot ."; 
     case Keys.HanjaMode: 
      return "(Description of HanjaMode key)"; 
     default: 
      return k.ToString(); 
    } 
} 

No estoy seguro de si necesita el bit & ~Keys.Modifiers o no - si lo hace, es probable que desee escribir más código para manejar los modificadores, pero he hecho cosas similares antes.

1

Si sólo desea suministrar descripción de algunas teclas, puede recorrer la System.Windows.Forms.Keys y suministrar un método que por defecto el nombre de enumeración clave:

private void Form1_Load(object sender, EventArgs e) 
{ 
    foreach (System.Windows.Forms.Keys key in Enum.GetValues(typeof(System.Windows.Forms.Keys))) 
    { 
     comboBoxKeys.Items.Add(new { Value = key, Description = GetDescription(key) }); 
    } 

    comboBoxKeys.DisplayMember = "Description"; 
} 

private string GetDescription(System.Windows.Forms.Keys key) 
{ 
    switch(key) 
    { 
     case Keys.OemPipe: 
      return "Better oem pipe description"; 

     case Keys.HanjaMode: 
      return "Ninja mode"; 

     default: 
      return key.ToString(); // default name 
    } 
} 
0

Puede asignar atributos a las enumeraciones. Esta es la mejor manera. De lo contrario, terminará teniendo que mantener diccionarios paralelos o una lista creciente de declaraciones switch-case.

Así es como usted marcar la enumeración:

public enum MyEnums 
{ 
    [Description("OEM Pipe")] 
    OemPipe, 

    [Description("Hanja Mode")] 
    HanjaMode 
} 

puede recuperar el atributo Description a través de un método de extensión:

public static string ToEnumDescription(this Enum value) 
{ 
    FieldInfo fi = value.GetType().GetField(value.ToString()); 

    DescriptionAttribute[] attributes = 
     (DescriptionAttribute[])fi.GetCustomAttributes(
     typeof(DescriptionAttribute), 
     false); 

    if (attributes != null && 
     attributes.Length > 0) 
     return attributes[0].Description; 
    else 
     return value.ToString(); 
} 

Para recuperar realmente la descripción enumeración, que podríamos llamar de esta camino;

var enumAsText = theEnum.ToEnumDescription(); 

También puede hacer esto:

MyEnums.OemPipe.ToEnumDescription(); 
+0

Está usando una enumeración existente ('System.Windows.Forms.Keys') y, por lo tanto, no puede agregar atributos' Description'. – jnylen

+0

LOL, que no se declaró inicialmente ... – code4life

1

"OEM" significa fabricante de equipos originales. En otras palabras, el tipo de empresa que fabrica teclados. Estos nombres son especiales porque en un teclado 'normal', no hay una clave dedicada para generar | o activar los radios Hanja en coreano (adivinar). Obtener un | requiere mantener presionada la tecla Mayús en la mayoría de los diseños. Algunos fabricantes de teclados pueden agregar claves al diseño estándar que hacen esto.

Lo cual debería darle un poco de pausa, es poco probable que estas teclas estén disponibles en el teclado del usuario, por lo que presentarlas como posibles atajos de teclado no es útil. Lo que es más importante, usar la cadena que obtienes de Keys es una mala idea en sí misma. Le dará un gran dolor de cabeza cuando necesite localizar su aplicación algún día para que los otros 5 mil millones de personas en este mundo se conviertan en clientes de pago.

+0

Es cierto. Siempre odié la localización, es una de las cosas más molestas en la programación ... – Tibi

3

Supongo que está permitiendo que el usuario asigne claves desde su aplicación (como teclas de acceso directo o controles de juegos). Desafortunadamente, no hay una manera fácil de obtener descripciones amigables para las claves (Microsoft no proporciona una API equivalente), por lo que deberá crear una asignación por su cuenta.

Como muestra la respuesta actualmente aceptada, usar un archivo de recursos es una excelente forma de hacerlo para permitir la internacionalización de su aplicación.

Para referencia, aquí es una aplicación de fuerza bruta completa de la enumeración Keys que escribí hace un tiempo: (usando un archivo de recursos todavía se recomienda, sin embargo)

public static string GetDescription(Keys key) 
{ 
    switch (key) 
    { 
     //letters 
     case Keys.A: case Keys.B: case Keys.C: case Keys.D: case Keys.E: case Keys.F: 
     case Keys.G: case Keys.H: case Keys.I: case Keys.J: case Keys.K: case Keys.L: 
     case Keys.M: case Keys.N: case Keys.O: case Keys.P: case Keys.Q: case Keys.R: 
     case Keys.S: case Keys.T: case Keys.U: case Keys.V: case Keys.W: case Keys.X: 
     case Keys.Y: case Keys.Z: 
      return Enum.GetName(typeof(Keys), key); 

     //digits 
     case Keys.D0: 
      return "0"; 
     case Keys.NumPad0: 
      return "Number Pad 0"; 
     case Keys.D1: 
      return "1"; 
     case Keys.NumPad1: 
      return "Number Pad 1"; 
     case Keys.D2: 
      return "2"; 
     case Keys.NumPad2: 
      return "Number Pad 2"; 
     case Keys.D3: 
      return "3"; 
     case Keys.NumPad3: 
      return "Number Pad 3"; 
     case Keys.D4: 
      return "4"; 
     case Keys.NumPad4: 
      return "Number Pad 4"; 
     case Keys.D5: 
      return "5"; 
     case Keys.NumPad5: 
      return "Number Pad 5"; 
     case Keys.D6: 
      return "6"; 
     case Keys.NumPad6: 
      return "Number Pad 6"; 
     case Keys.D7: 
      return "7"; 
     case Keys.NumPad7: 
      return "Number Pad 7"; 
     case Keys.D8: 
      return "8"; 
     case Keys.NumPad8: 
      return "Number Pad 8"; 
     case Keys.D9: 
      return "9"; 
     case Keys.NumPad9: 
      return "Number Pad 9"; 

     //punctuation 
     case Keys.Add: 
      return "Number Pad +"; 
     case Keys.Subtract: 
      return "Number Pad -"; 
     case Keys.Divide: 
      return "Number Pad /"; 
     case Keys.Multiply: 
      return "Number Pad *"; 
     case Keys.Space: 
      return "Spacebar"; 
     case Keys.Decimal: 
      return "Number Pad ."; 

     //function 
     case Keys.F1: case Keys.F2: case Keys.F3: case Keys.F4: case Keys.F5: 
     case Keys.F6: case Keys.F7: case Keys.F8: case Keys.F9: case Keys.F10: 
     case Keys.F11: case Keys.F12: case Keys.F13: case Keys.F14: case Keys.F15: 
     case Keys.F16: case Keys.F17: case Keys.F18: case Keys.F19: case Keys.F20: 
     case Keys.F21: case Keys.F22: case Keys.F23: case Keys.F24: 
      return Enum.GetName(typeof(Keys), key); 

     //navigation 
     case Keys.Up: 
      return "Up Arrow"; 
     case Keys.Down: 
      return "Down Arrow"; 
     case Keys.Left: 
      return "Left Arrow"; 
     case Keys.Right: 
      return "Right Arrow"; 
     case Keys.Prior: 
      return "Page Up"; 
     case Keys.Next: 
      return "Page Down"; 
     case Keys.Home: 
      return "Home"; 
     case Keys.End: 
      return "End"; 

     //control keys 
     case Keys.Back: 
      return "Backspace"; 
     case Keys.Tab: 
      return "Tab"; 
     case Keys.Escape: 
      return "Escape"; 
     case Keys.Enter: 
      return "Enter"; 
     case Keys.Shift: case Keys.ShiftKey: 
      return "Shift"; 
     case Keys.LShiftKey: 
      return "Shift (Left)"; 
     case Keys.RShiftKey: 
      return "Shift (Right)"; 
     case Keys.Control: case Keys.ControlKey: 
      return "Control"; 
     case Keys.LControlKey: 
      return "Control (Left)"; 
     case Keys.RControlKey: 
      return "Control (Right)"; 
     case Keys.Menu: case Keys.Alt: 
      return "Alt"; 
     case Keys.LMenu: 
      return "Alt (Left)"; 
     case Keys.RMenu: 
      return "Alt (Right)"; 
     case Keys.Pause: 
      return "Pause"; 
     case Keys.CapsLock: 
      return "Caps Lock"; 
     case Keys.NumLock: 
      return "Num Lock"; 
     case Keys.Scroll: 
      return "Scroll Lock"; 
     case Keys.PrintScreen: 
      return "Print Screen"; 
     case Keys.Insert: 
      return "Insert"; 
     case Keys.Delete: 
      return "Delete"; 
     case Keys.Help: 
      return "Help"; 
     case Keys.LWin: 
      return "Windows (Left)"; 
     case Keys.RWin: 
      return "Windows (Right)"; 
     case Keys.Apps: 
      return "Context Menu"; 

     //browser keys 
     case Keys.BrowserBack: 
      return "Browser Back"; 
     case Keys.BrowserFavorites: 
      return "Browser Favorites"; 
     case Keys.BrowserForward: 
      return "Browser Forward"; 
     case Keys.BrowserHome: 
      return "Browser Home"; 
     case Keys.BrowserRefresh: 
      return "Browser Refresh"; 
     case Keys.BrowserSearch: 
      return "Browser Search"; 
     case Keys.BrowserStop: 
      return "Browser Stop"; 

     //media keys 
     case Keys.VolumeDown: 
      return "Volume Down"; 
     case Keys.VolumeMute: 
      return "Volume Mute"; 
     case Keys.VolumeUp: 
      return "Volume Up"; 
     case Keys.MediaNextTrack: 
      return "Next Track"; 
     case Keys.Play: 
     case Keys.MediaPlayPause: 
      return "Play"; 
     case Keys.MediaPreviousTrack: 
      return "Previous Track"; 
     case Keys.MediaStop: 
      return "Stop"; 
     case Keys.SelectMedia: 
      return "Select Media"; 

     //IME keys 
     case Keys.HanjaMode: case Keys.JunjaMode: case Keys.HangulMode: 
     case Keys.FinalMode: //duplicate values: Hanguel, Kana, Kanji 
     case Keys.IMEAccept: case Keys.IMEConvert: //duplicate: IMEAceept 
     case Keys.IMEModeChange: case Keys.IMENonconvert: 
      return null; 

     //special keys 
     case Keys.LaunchMail: 
      return "Launch Mail"; 
     case Keys.LaunchApplication1: 
      return "Launch Favorite Application 1"; 
     case Keys.LaunchApplication2: 
      return "Launch Favorite Application 2"; 
     case Keys.Zoom: 
      return "Zoom"; 

     //oem keys 
     case Keys.OemSemicolon: //oem1 
      return ";"; 
     case Keys.OemQuestion: //oem2 
      return "?"; 
     case Keys.Oemtilde:  //oem3 
      return "~"; 
     case Keys.OemOpenBrackets: //oem4 
      return "["; 
     case Keys.OemPipe: //oem5 
      return "|"; 
     case Keys.OemCloseBrackets: //oem6 
      return "]"; 
     case Keys.OemQuotes:  //oem7 
      return "'"; 
     case Keys.OemBackslash: //oem102 
      return "/"; 
     case Keys.Oemplus: 
      return "+"; 
     case Keys.OemMinus: 
      return "-"; 
     case Keys.Oemcomma: 
      return ","; 
     case Keys.OemPeriod: 
      return "."; 

     //unsupported oem keys 
     case Keys.Oem8: 
     case Keys.OemClear: 
      return null; 

     //unsupported other keys 
     case Keys.None:  case Keys.LButton: case Keys.RButton: case Keys.MButton: 
     case Keys.XButton1: case Keys.XButton2: case Keys.Clear: case Keys.Sleep: 
     case Keys.Cancel: case Keys.LineFeed: case Keys.Select: case Keys.Print: 
     case Keys.Execute: case Keys.Separator: case Keys.ProcessKey: case Keys.Packet: 
     case Keys.Attn:  case Keys.Crsel: case Keys.Exsel: case Keys.EraseEof: 
     case Keys.NoName: case Keys.Pa1:  case Keys.KeyCode: case Keys.Modifiers: 
      return null; 

     default: 
      throw new NotSupportedException(Enum.GetName(typeof(Keys), key)); 
    } 
} 

Puede convertir esto en un archivo de recursos ejecutando el siguiente programa y luego agregando output.resx a su aplicación como recurso.

static void Main(string[] args) 
{ 
    using(ResXResourceWriter writer = new ResXResourceWriter("output.resx")) 
    { 
     //since there are duplicate values, we need to clumsily look at each name, then parse 
     foreach (string name in Enum.GetNames(typeof(Keys))) 
     { 
      object value = Enum.Parse(typeof(Keys), name); 
      string description = GetDescription((Keys)value); 

      if (description != null) 
       writer.AddResource(new ResXDataNode(name, description)); 
     } 
    } 
} 

Esto le dará un archivo de recursos que se puede utilizar de la manera explicada en la respuesta aceptada.

Cuestiones relacionadas