Desative o Tabstop entre colunas em um datagrid WPF
-
22-09-2019 - |
Pergunta
Eu tenho um datagrid WPF Toolkit com colunas Mulitple. Estou tentando obter um comportamento em que você possa guiar na grade usando a guia e depois a guia novamente usando uma única guia. Por exemplo, eu não quero guardar todas as colunas ou células da grade, apenas uma vez e uma vez fora.
Existe uma solução simples, tentei definir a tabnavigação como uma vez, juntamente com o desativar o TabStop (não mostrado no código abaixo) e definir tabnavigação nas colunas como nenhuma, mas sem sucesso.
Há algo que estou perdendo ou preciso lidar com a tecla de guia no código?
<my:DataGrid Name="datagrid"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserAddRows="False" CanUserDeleteRows="False"
Background="White"
KeyboardNavigation.TabNavigation="Once">
<my:DataGrid.Columns>
<my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" ></my:DataGridTextColumn>
<my:DataGridTextColumn x:Name="Ticker" Header="Ticker" Width="1*" KeyboardNavigation.TabNavigation="None"></my:DataGridTextColumn>
<my:DataGridTextColumn x:Name="OfficialName" Header="Name" Width="3*" KeyboardNavigation.TabNavigation="None"></my:DataGridTextColumn>
</my:DataGrid.Columns>
</my:DataGrid>
Solução
É interessante que definir a navigação do teclado diretamente no DataGridTextColumn's não funciona. Uma alternativa que deve funcionar é configurar um estilo DataGridCell.
<toolkit:DataGrid.CellStyle>
<Style TargetType="{x:Type toolkit:DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop"
Value="False" />
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="KeyboardNavigation.IsTabStop"
Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</toolkit:DataGrid.CellStyle>
Anexar isso ao DataGrid garantirá que uma célula seja apenas um tabstop se já estiver selecionado. No entanto, se você estiver selecionando linhas completas e não tiver seleçãounit = "Cell" definido no DataGrid, ele ainda percorre cada coluna da linha atualmente selecionada.
Em vez disso, podemos criar vários estilos de células como recursos dentro do DataGrid:
<toolkit:DataGrid.Resources>
<Style x:Key="SelectableCellStyle"
TargetType="{x:Type toolkit:DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop"
Value="False" />
<Style.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter Property="KeyboardNavigation.IsTabStop"
Value="True" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type toolkit:DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop"
Value="False" />
</Style>
</toolkit:DataGrid.Resources>
Agora, temos um estilo sendo aplicado a todos os datagridCells por padrão e desligando o TabStop, e um estilo de chave que permite a seleção quando a célula (ou linha inteira) é selecionada. A aplicação desse estilo a apenas uma única coluna nos dará o mesmo efeito de abra único, permitindo que a linha inteira e todas as suas colunas sejam selecionadas.
<my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" CellStyle={StaticResource SelectableCellStyle}"/>
Isso também para de tabular no datagrid se nada for selecionado, o que pode ser preferido ou não, dependendo da situação em que você o estiver usando.
Outras dicas
Obrigado Rmoore. Para que a parada da guia seja desativada para colunas, peguei sua resposta e a modifiquei um pouco;
<my:DataGrid Name="datagrid"
AutoGenerateColumns="False" IsReadOnly="True"
CanUserAddRows="False" CanUserDeleteRows="False"
Background="White"
KeyboardNavigation.TabNavigation="Once"
SelectionUnit="FullRow">
<my:DataGrid.Columns>
<my:DataGridTextColumn x:Name="ID" Header="ID" Width="1*" ></my:DataGridTextColumn>
<my:DataGridTextColumn x:Name="Ticker" Header="Ticker" Width="1*">
<my:DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type my:DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"></Setter>
</Style>
</my:DataGridTextColumn.CellStyle>
</my:DataGridTextColumn>
<my:DataGridTextColumn x:Name="OfficialName" Header="Name" Width="3*">
<my:DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type my:DataGridCell}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"></Setter>
</Style>
</my:DataGridTextColumn.CellStyle>
</my:DataGridTextColumn>
</my:DataGrid.Columns>
</my:DataGrid>
Então, truques;
- Seleçãonit = "Fullrow" faz com que a GUI pareça que você está fazendo as coisas uma linha de cada vez (como eu queria).
- Ao adicionar um estilo de célula às colunas em que quero desativar o Tabstop (mas não incluí-lo naqueles em que gostaria de parar) me permitiu assumir o controle sobre em quais células a tecla da guia navegaria. - A keyboardnavigation.tabnavigation não tem efeito quando definida nas colunas.
Sei que essa é uma pergunta muito antiga, mas estou postando isso aqui, caso isso ajude alguém. Embora a resposta aceita seja boa, não acredito que ela cubra o caso em que há outro controle na mesma janela, e você gostaria de guiar no DataGrid
a partir desse controle. Além disso, você pode querer o comportamento, conforme descrito na pergunta original (guia única, uma guia única, sem tabelas através de células/colunas). Esta solução tem como objetivo conseguir isso.
Observação: Esta solução está assumindo que você deseja o seu SelectionUnit
ser FullRow
na tua DataGrid
.
Primeiro, aqui está o Style
Para se aplicar ao DataGrid
:
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style.Setters>
<Setter Property="Focusable" Value="True"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell">
<Style.Setters>
<Setter Property="Focusable" Value="False"/>
</Style.Setters>
</Style>
</DataGrid.Resources>
Esse estilo permite focar em linhas, mas evita o foco nas células individuais, o que mantém o foco consistente com o SelectionUnit
do FullRow
. O gatilho definido dentro desse estilo é opcional - é necessário apenas se você deseja selecionar automaticamente a linha quando receber foco.
No meu caso, eu queria o comportamento de uma única guia em / guia, então eu também defino o KeyboardNavigation.TabNavigation
propriedade no meu DataGrid
= "Uma vez".
<DataGrid SelectionUnit="FullRow" KeyboardNavigation.TabNavigation="Once">
Com essa abordagem, ainda posso usar as teclas de seta para cima/para baixo para percorrer linhas quando o DataGrid
Recebe o foco, mas ainda posso guardar rapidamente se quiser mover o foco para o próximo controle na ordem da guia.