WPF: OnKeyDown () não sendo chamado para a tecla de espaço no controle derivado WPF TextBox

StackOverflow https://stackoverflow.com/questions/1458748

  •  12-09-2019
  •  | 
  •  

Pergunta

Em um aplicativo WPF, eu tenho um controle que eu ter derivado de TextBox como esta:

public class SelectableTextBlock : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        e.Handled = false;
    }
}

O método OnKeyDown não é chamado quando entrar um espaço na caixa de texto, nem quando bater Backspace, mas faz fogo por outra entrada, incluindo caracteres imprimíveis normais (por exemplo, 'a') e teclas modificadoras (por exemplo).

Estou usando este controle com IsReadOnly conjunto para true para que eu possa exibir selecionável, texto editável. O controle usado dentro DataGrid do WPFToolkit, e eu quero eventos KeyDown para propagar-se a grade de dados, mesmo que o SelectableTextBlock tem o foco, que é por isso que eu estou usando um controle personalizado para marcar explicitamente o evento como não processada.

O problema é que o evento não é mesmo fazê-lo para o meu controle para determinadas chaves. Eu não posso simplesmente usar OnPreviewKeyDown no DataGrid para contornar isso, já que eu quero outros controles usados ??na grade de dados de engolir o evento espaço KeyDown.

Alguém sabe como posso obter o evento KeyDown para a chave espaço para propagar-se?

Graças.

Foi útil?

Solução 2

Parece que o problema é que o espaço (e backspace etc.) tecla pressionada evento está sendo já tratadas no TextBox, antes de bolhas para o meu controle derivado. Eu assumo como parte do processo de composição de texto, como Wim postou.

Para solucionar esse, eu adicionei um manipulador que irá receber a chave para baixo o evento, mesmo que já tenha sido manuseado, e define seu membro tratado como false, para permitir que ele para continuar borbulhando normalmente. No exemplo abaixo, ele só faz isso para as chaves de espaço, mas no meu caso eu vou ter de fazê-lo fazer isso para todos os eventos-chave que eu realmente não quer manipulados na minha SelectedableTextBlock, como eu não sei o que os principais eventos pais talvez possa estar interessado ainda.

public class SelectableTextBlock : TextBox
{
    public SelectableTextBlock() : base()
    {
        this.AddHandler(SelectableTextBlock.KeyDownEvent, new RoutedEventHandler(HandleHandledKeyDown), true);
    }

    public void HandleHandledKeyDown(object sender, RoutedEventArgs e)
    {
        KeyEventArgs ke = e as KeyEventArgs;
        if (ke.Key == Key.Space)
        {
            ke.Handled = false;
        }
    }
    ...
}

É claro que estou interessado ainda se alguém tem uma solução melhor ...

Obrigado, E.

Outras dicas

O evento PreviewKeyDown existe exatamente para este tipo de coisa.

private void spacebarHandler_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
        e.Handled = true;
}

Seu manipulador KeyDown nunca vai receber o evento KeyDown para a barra de espaço.

Eu tive esse problema com espaços e eventos uma vez em uma caixa de texto. São os eventos não acionado somente quando você adicionar ou remover um caractere de espaço?

Isto é o que eu tenho como uma resposta: ( http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b )

Como alguns IMEs tratará espaços em branco de teclas como parte do processo de composição de texto, é por isso que ele come por Avalon denunciar o texto composited correta através TextInput evento.

Eu poderia ser completamente fora do escopo, mas lendo esta discussão emmideatly me fez pensar essa questão, uma vez que eu tinha.

Atenciosamente, Wim

Derive uma palavra a dizer, RestrictKeysTextBox de TextBox.

public class RestrictKeysTextBox : TextBox
{
    ....
}

Substituir o evento OnPreviewKeyDown na RestrictKeysTextBox.

Coloque a lógica neste override assim:

if (e.Key == Key.Space)
{
    e.Handled = true;
}

Bind a instância do RestrictKeysTextBox ao seu DataGrid.

Isso deve funcionar sem substituir o OnPreviewKeyDown no DataGrid e eliminar os problemas associados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top