How to get pressed char from System.Windows.Input.KeyEventArgs?

You have e.Key property you can use for just that. Here's a link to msdn.

Edit:
I didn't realize you need the actual char. You can take a look here They say that in WPF you can do it using some Win32 APIs, while in Silverlight it seems rather difficult. Also you can look at KeyInterop.VirtualKeyFromKey - you can convert the WPF Key enum into a WinForms Keys enumeration, which does give you some more information. I haven't tried any of the solutions, so I don't know if any of them will work.
And one last thing. Why do you need the char from the KeyDown/Up event? Are you sure you can't use the TextChanged event instead? It will be much easier to get the exact char, if you can.


Sometimes you just need to solved the problem with a sledgehammer.

char KeyToChar(Key key) {

    if (Keyboard.IsKeyDown(Key.LeftAlt)  ||
        Keyboard.IsKeyDown(Key.RightAlt) ||
        Keyboard.IsKeyDown(Key.LeftCtrl) ||
        Keyboard.IsKeyDown(Key.RightAlt))
    {
        return '\x00';
    }

    bool caplock  = Console.CapsLock;
    bool shift    = Keyboard.IsKeyDown(Key.LeftShift) || 
                            Keyboard.IsKeyDown(Key.RightShift);
    bool iscap    = (caplock && !shift) || (!caplock && shift);

        switch(key) {
            case Key.Enter:           return '\n';
            case Key.A:               return (iscap ? 'A' : 'a');
            case Key.B:               return (iscap ? 'B' : 'b');
            case Key.C:               return (iscap ? 'C' : 'c');
            case Key.D:               return (iscap ? 'D' : 'd');
            case Key.E:               return (iscap ? 'E' : 'e');
            case Key.F:               return (iscap ? 'F' : 'f');
            case Key.G:               return (iscap ? 'G' : 'g');
            case Key.H:               return (iscap ? 'H' : 'h');
            case Key.I:               return (iscap ? 'I' : 'i');
            case Key.J:               return (iscap ? 'J' : 'j');
            case Key.K:               return (iscap ? 'K' : 'k');
            case Key.L:               return (iscap ? 'L' : 'l');
            case Key.M:               return (iscap ? 'M' : 'm');
            case Key.N:               return (iscap ? 'N' : 'n');
            case Key.O:               return (iscap ? 'O' : 'o');
            case Key.P:               return (iscap ? 'P' : 'p');
            case Key.Q:               return (iscap ? 'Q' : 'q');
            case Key.R:               return (iscap ? 'R' : 'r');
            case Key.S:               return (iscap ? 'S' : 's');
            case Key.T:               return (iscap ? 'T' : 't');
            case Key.U:               return (iscap ? 'U' : 'u');
            case Key.V:               return (iscap ? 'V' : 'v');
            case Key.W:               return (iscap ? 'W' : 'w');
            case Key.X:               return (iscap ? 'X' : 'x');
            case Key.Y:               return (iscap ? 'Y' : 'y');
            case Key.Z:               return (iscap ? 'Z' : 'z');
            case Key.D0:              return (shift ? ')' : '0');
            case Key.D1:              return (shift ? '!' : '1');
            case Key.D2:              return (shift ? '@' : '2');
            case Key.D3:              return (shift ? '#' : '3');
            case Key.D4:              return (shift ? '$' : '4');
            case Key.D5:              return (shift ? '%' : '5');
            case Key.D6:              return (shift ? '^' : '6');
            case Key.D7:              return (shift ? '&' : '7');
            case Key.D8:              return (shift ? '*' : '8');
            case Key.D9:              return (shift ? '(' : '9');
            case Key.OemPlus:         return (shift ? '+' : '=');
            case Key.OemMinus:        return (shift ? '_' : '-');
            case Key.OemQuestion:     return (shift ? '?' : '/');
            case Key.OemComma:        return (shift ? '<' : ',');
            case Key.OemPeriod:       return (shift ? '>' : '.');
            case Key.OemOpenBrackets: return (shift ? '{' : '[');
            case Key.OemQuotes:       return (shift ? '"' : '\'');
            case Key.Oem1:            return (shift ? ':' : ';');
            case Key.Oem3:            return (shift ? '~' : '`');                   
            case Key.Oem5:            return (shift ? '|' : '\\');
            case Key.Oem6:            return (shift ? '}' : ']');
            case Key.Tab:             return '\t';
            case Key.Space:           return ' ';

            // Number Pad
            case Key.NumPad0:         return '0';
            case Key.NumPad1:         return '1';
            case Key.NumPad2:         return '2';
            case Key.NumPad3:         return '3';
            case Key.NumPad4:         return '4';
            case Key.NumPad5:         return '5';
            case Key.NumPad6:         return '6';
            case Key.NumPad7:         return '7';
            case Key.NumPad8:         return '8';
            case Key.NumPad9:         return '9';
            case Key.Subtract:        return '-';
            case Key.Add:             return '+';
            case Key.Decimal:         return '.';
            case Key.Divide:          return '/';
            case Key.Multiply:        return '*';

            default:                  return '\x00';
    }
}

Here's a more powerful version of the above code:

public struct IoCmd_t {
    public Key    key;
    public bool   printable;
    public char   character;
    public bool   shift;
    public bool   ctrl;
    public bool   alt;
    public int    type; //sideband
    public string s;    //sideband
};

public void KeyToChar(Key key, ref IoCmd_t KeyDecode) {
    bool iscap;
    bool caplock;
    bool shift;

    KeyDecode.key   = key;

    KeyDecode.alt   = Keyboard.IsKeyDown(Key.LeftAlt) || 
                      Keyboard.IsKeyDown(Key.RightAlt);

    KeyDecode.ctrl  = Keyboard.IsKeyDown(Key.LeftCtrl) ||
                      Keyboard.IsKeyDown(Key.RightCtrl);

    KeyDecode.shift = Keyboard.IsKeyDown(Key.LeftShift) ||
                      Keyboard.IsKeyDown(Key.RightShift);

    if (KeyDecode.alt || KeyDecode.ctrl) {
        KeyDecode.printable = false;                
        KeyDecode.type      = 1;                
    }
    else {
        KeyDecode.printable = true;
        KeyDecode.type      = 0;
    }

    shift    = KeyDecode.shift;
    caplock  = Console.CapsLock; //Keyboard.IsKeyToggled(Key.CapsLock);
    iscap    = (caplock && !shift) || (!caplock && shift);

    switch(key) {
        case Key.Enter:           KeyDecode.character = '\n'; return;
        case Key.A:               KeyDecode.character = (iscap ? 'A' : 'a');  return;
        case Key.B:               KeyDecode.character = (iscap ? 'B' : 'b');  return;
        case Key.C:               KeyDecode.character = (iscap ? 'C' : 'c');  return;
        case Key.D:               KeyDecode.character = (iscap ? 'D' : 'd');  return;
        case Key.E:               KeyDecode.character = (iscap ? 'E' : 'e');  return;
        case Key.F:               KeyDecode.character = (iscap ? 'F' : 'f');  return;
        case Key.G:               KeyDecode.character = (iscap ? 'G' : 'g');  return;
        case Key.H:               KeyDecode.character = (iscap ? 'H' : 'h');  return;
        case Key.I:               KeyDecode.character = (iscap ? 'I' : 'i');  return;
        case Key.J:               KeyDecode.character = (iscap ? 'J' : 'j');  return;
        case Key.K:               KeyDecode.character = (iscap ? 'K' : 'k');  return;
        case Key.L:               KeyDecode.character = (iscap ? 'L' : 'l');  return;
        case Key.M:               KeyDecode.character = (iscap ? 'M' : 'm');  return;
        case Key.N:               KeyDecode.character = (iscap ? 'N' : 'n');  return;
        case Key.O:               KeyDecode.character = (iscap ? 'O' : 'o');  return;
        case Key.P:               KeyDecode.character = (iscap ? 'P' : 'p');  return;
        case Key.Q:               KeyDecode.character = (iscap ? 'Q' : 'q');  return;
        case Key.R:               KeyDecode.character = (iscap ? 'R' : 'r');  return;
        case Key.S:               KeyDecode.character = (iscap ? 'S' : 's');  return;
        case Key.T:               KeyDecode.character = (iscap ? 'T' : 't');  return;
        case Key.U:               KeyDecode.character = (iscap ? 'U' : 'u');  return;
        case Key.V:               KeyDecode.character = (iscap ? 'V' : 'v');  return;
        case Key.W:               KeyDecode.character = (iscap ? 'W' : 'w');  return;
        case Key.X:               KeyDecode.character = (iscap ? 'X' : 'x');  return;
        case Key.Y:               KeyDecode.character = (iscap ? 'Y' : 'y');  return;
        case Key.Z:               KeyDecode.character = (iscap ? 'Z' : 'z');  return;
        case Key.D0:              KeyDecode.character = (shift ? ')' : '0');  return;
        case Key.D1:              KeyDecode.character = (shift ? '!' : '1');  return;
        case Key.D2:              KeyDecode.character = (shift ? '@' : '2');  return;
        case Key.D3:              KeyDecode.character = (shift ? '#' : '3');  return;
        case Key.D4:              KeyDecode.character = (shift ? '$' : '4');  return;
        case Key.D5:              KeyDecode.character = (shift ? '%' : '5');  return;
        case Key.D6:              KeyDecode.character = (shift ? '^' : '6');  return;
        case Key.D7:              KeyDecode.character = (shift ? '&' : '7');  return;
        case Key.D8:              KeyDecode.character = (shift ? '*' : '8');  return;
        case Key.D9:              KeyDecode.character = (shift ? '(' : '9');  return;
        case Key.OemPlus:         KeyDecode.character = (shift ? '+' : '=');  return;
        case Key.OemMinus:        KeyDecode.character = (shift ? '_' : '-');  return;
        case Key.OemQuestion:     KeyDecode.character = (shift ? '?' : '/');  return;
        case Key.OemComma:        KeyDecode.character = (shift ? '<' : ',');  return;
        case Key.OemPeriod:       KeyDecode.character = (shift ? '>' : '.');  return;
        case Key.OemOpenBrackets: KeyDecode.character = (shift ? '{' : '[');  return;
        case Key.OemQuotes:       KeyDecode.character = (shift ? '"' : '\''); return;
        case Key.Oem1:            KeyDecode.character = (shift ? ':' : ';');  return;
        case Key.Oem3:            KeyDecode.character = (shift ? '~' : '`');  return;
        case Key.Oem5:            KeyDecode.character = (shift ? '|' : '\\'); return;
        case Key.Oem6:            KeyDecode.character = (shift ? '}' : ']');  return;
        case Key.Tab:             KeyDecode.character = '\t'; return;
        case Key.Space:           KeyDecode.character = ' '; return;

        // Number Pad
        case Key.NumPad0:         KeyDecode.character = '0'; return;
        case Key.NumPad1:         KeyDecode.character = '1'; return;
        case Key.NumPad2:         KeyDecode.character = '2'; return;
        case Key.NumPad3:         KeyDecode.character = '3'; return;
        case Key.NumPad4:         KeyDecode.character = '4'; return;
        case Key.NumPad5:         KeyDecode.character = '5'; return;
        case Key.NumPad6:         KeyDecode.character = '6'; return;
        case Key.NumPad7:         KeyDecode.character = '7'; return;
        case Key.NumPad8:         KeyDecode.character = '8'; return;
        case Key.NumPad9:         KeyDecode.character = '9'; return;
        case Key.Subtract:        KeyDecode.character = '-'; return;
        case Key.Add:             KeyDecode.character = '+'; return;
        case Key.Decimal:         KeyDecode.character = '.'; return;
        case Key.Divide:          KeyDecode.character = '/'; return;
        case Key.Multiply:        KeyDecode.character = '*'; return;

        default:
            KeyDecode.type      = 1;
            KeyDecode.printable = false;
            KeyDecode.character = '\x00'; 
            return;
    } //switch          
} // function

See this post... how to capture the '#' character on different locale keyboards in WPF/C#?

it has a utility function called GetCharFromKey(Key key) which gets locale specific character from the Key of the Keyboard event args.

Very useful.