Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A interface do usuário aninhada é uma interface do usuário que expõe controles aninhados acionáveis colocados dentro de um contêiner que também podem ter foco independente.
Você pode usar a interface de usuário hierárquica para apresentar a um usuário opções adicionais que ajudam a agilizar a realização de ações importantes. No entanto, quanto mais ações você expõe, mais complicada a interface do usuário se torna. Você precisa tomar cuidado extra ao optar por usar esse padrão de interface do usuário. Este artigo fornece diretrizes para ajudá-lo a determinar o melhor curso de ação para sua interface do usuário específica.
APIs importantes: classe ListView, classe GridView
Neste artigo, discutimos a criação de UI aninhada em ListView e GridView. Embora esta seção não fale sobre outros casos de interface do usuário aninhados, esses conceitos são transferíveis. Antes de começar, você deve estar familiarizado com as diretrizes gerais para usar controles ListView ou GridView em sua interface do usuário, que são encontradas nos artigos Listas e Exibição de Lista e Exibição de Grade.
Neste artigo, usamos os termos lista, item de lista e UI aninhada, conforme definido aqui:
- A lista refere-se a uma coleção de itens contidos em uma exibição de lista ou exibição de grade.
- Item de lista refere-se a um item individual em que um usuário pode agir em uma lista.
- UI aninhada refere-se a elementos da interface do usuário dentro de um item de lista que um usuário pode tomar ações independentemente de executar ações no próprio item da lista.
OBSERVAÇÃO ListView e GridView derivam da classe ListViewBase , portanto, elas têm a mesma funcionalidade, mas exibem dados de forma diferente. Neste artigo, quando falamos sobre listas, as informações se aplicam aos controles ListView e GridView.
Ações primárias e secundárias
Ao criar a interface do usuário com uma lista, considere quais ações o usuário pode tomar desses itens de lista.
- Um usuário pode clicar no item para executar uma ação?
- Normalmente, clicar em um item de lista inicia uma ação, mas não precisa.
- Há mais de uma ação que o usuário pode executar?
- Por exemplo, tocar em um email em uma lista abre esse email. No entanto, pode haver outras ações, como excluir o email, que o usuário gostaria de executar sem abri-lo primeiro. Isso beneficiaria o usuário para acessar essa ação diretamente na lista.
- Como as ações devem ser expostas ao usuário?
- Considere todos os tipos de entrada. Algumas interfaces do usuário aninhadas funcionam muito bem com um método de entrada, mas podem não funcionar com outros métodos.
A ação principal é o que o usuário espera que aconteça quando pressionar o item de lista.
Ações secundárias normalmente são aceleradores associados a itens de lista. Esses aceleradores podem ser para o gerenciamento de listas ou ações relacionadas ao item de lista.
Opções para ações secundárias
Ao criar a interface do usuário da lista, primeiro você precisa garantir que todos os métodos de entrada compatíveis com o Windows sejam considerados. Para obter mais informações sobre diferentes tipos de entrada, consulte o guia de entrada.
Depois de certificar-se de que seu aplicativo dá suporte a todas as entradas compatíveis com o Windows, você deve decidir se as ações secundárias do aplicativo são importantes o suficiente para expor como aceleradores na lista principal. Lembre-se de que quanto mais ações você expõe, mais complicada a interface do usuário se torna. Você realmente precisa expor as ações secundárias na interface do usuário da lista principal ou pode colocá-las em outro lugar?
Você pode considerar expor ações adicionais na interface do usuário da lista principal quando essas ações precisarem ser acessíveis por qualquer entrada o tempo todo.
Se você decidir que não é necessário colocar ações secundárias na interface do usuário da lista principal, há várias outras maneiras de expô-las ao usuário. Aqui estão algumas opções que você pode considerar para onde colocar ações secundárias.
Colocar ações secundárias na página de detalhes
Coloque as ações secundárias na página para a qual o item de lista navega quando ele é pressionado. Quando você usa o padrão de lista/detalhes, a página de detalhes geralmente é um bom lugar para colocar ações secundárias.
Para obter mais informações, consulte o padrão de lista/detalhes.
Colocar ações secundárias em um menu de contexto
Coloque as ações secundárias em um menu de contexto que o usuário possa acessar por meio do clique com o botão direito do mouse ou pressionar e segurar. Isso oferece o benefício de permitir que o usuário execute uma ação, como excluir um email, sem precisar carregar a página de detalhes. É uma boa prática também disponibilizar essas opções na página de detalhes, pois os menus de contexto se destinam a ser aceleradores em vez da interface do usuário primária.
Para expor ações secundárias quando a entrada é de um gamepad ou controle remoto, recomendamos que você use um menu de contexto.
Para obter mais informações, consulte menus de contexto e flyouts.
Colocar ações secundárias na interface do usuário em hover para otimizar a entrada de ponteiro.
Se você espera que seu aplicativo seja usado com frequência com dispositivos de entrada com ponteiro, como mouse e caneta, e deseja tornar as ações secundárias prontamente disponíveis apenas para essas entradas, por isso você pode mostrar as ações secundárias apenas ao passar o mouse. Esse acelerador só fica visível quando uma entrada de ponteiro é usada, portanto, use as outras opções para dar suporte a outros tipos de entrada também.
Para obter mais informações, consulte as interações do Mouse.
Posicionamento da interface do usuário para ações primárias e secundárias
Se você decidir que as ações secundárias devem ser expostas na interface do usuário da lista principal, recomendamos as diretrizes a seguir.
Ao criar um item de lista com ações primárias e secundárias, coloque a ação primária à esquerda e às ações secundárias à direita. Nas culturas de leitura da esquerda para a direita, os usuários associam ações no lado esquerdo do item de lista como a ação primária.
Nesses exemplos, falamos sobre a interface do usuário da lista em que o item flui mais horizontalmente (é maior que sua altura). No entanto, você pode ter itens de lista que são mais quadrados em sua forma ou que são mais altos do que largos. Normalmente, esses são itens usados em uma grade. Para esses itens, se a lista não rolar verticalmente, você poderá colocar as ações secundárias na parte inferior do item de lista em vez de para o lado direito.
Considere todas as entradas
Ao decidir usar interfaces de usuário em camadas, avalie também a experiência do usuário com todos os tipos de entrada. Conforme mencionado anteriormente, a UI aninhada funciona muito bem para alguns tipos de entrada. No entanto, nem sempre funciona bem para outros. Em particular, o teclado, o controlador e as entradas remotas podem ter dificuldade para acessar elementos aninhados da interface do usuário. Siga as diretrizes abaixo para garantir que o Windows funcione com todos os tipos de entrada.
Gerenciamento de interface do usuário aninhada
Quando você tiver mais de uma ação aninhada no item de lista, recomendamos essa orientação para lidar com a navegação com teclado, gamepad, controle remoto ou outra entrada sem ponteiro.
Interface do usuário aninhada em que os itens de lista executam uma ação
Se a interface do usuário da lista com elementos aninhados der suporte a ações como invocar, selecionar (única ou múltipla) ou operações de arrastar e soltar, recomendamos o uso de técnicas de navegação com setas para percorrer os elementos aninhados da interface do usuário.
Gamepad
Quando a entrada é de um gamepad, forneça esta experiência do usuário:
- De A, a chave direcional direita coloca o foco em B.
- De B, a chave direcional direita coloca o foco em C.
- De C, a chave direcional direita não é op ou se houver um elemento de interface do usuário focalizável à direita de List, coloque o foco lá.
- De C, a tecla direcional esquerda foca em B.
- A partir de B, a tecla direcional esquerda coloca o foco em A.
- De A, a tecla direcional para a esquerda ou não realiza nenhuma operação, ou, se houver um elemento da interface do usuário focalizável à direita da lista, coloca o foco lá.
- A partir de A, B ou C, a tecla direcional para baixo coloca o foco em D.
- Do elemento de interface do usuário à esquerda do Item de Lista, a chave direcional direita coloca o foco em A.
- Do elemento da interface localizado à direita do Item de Lista, a seta direcional à esquerda foca em A.
Keyboard
Quando a entrada é de um teclado, essa é a experiência que o usuário obtém:
- A partir de A, a tecla tab coloca o foco em B.
- A partir de B, a tecla tab coloca o foco em C.
- Em C, a tecla tab desloca o foco para o próximo elemento focalizável da interface do usuário, seguindo a ordem de tabulação.
- De C, shift+tecla tab coloca o foco em B.
- A partir de B, shift+tab ou seta para a esquerda focaliza no A.
- A partir de A, a combinação de teclas Shift+Tab coloca o foco no próximo elemento da interface do usuário que possa ser focalizado na ordem inversa de tabulação.
- A partir de A, B ou C, a tecla de seta para baixo coloca o foco em D.
- Do elemento de interface do usuário à esquerda do Item de Lista, a tecla tab coloca o foco em A.
- Do elemento de interface do usuário à direita do Item de Lista, a tecla de guia shift coloca o foco em C.
Para obter essa interface do usuário, defina IsItemClickEnabled como true em sua lista. SelectionMode pode ser qualquer valor.
Para que o código implemente isso, consulte a seção Exemplo deste artigo.
Interface do usuário aninhada em que os itens de lista não executam uma ação
Você pode usar uma exibição de lista porque ela fornece virtualização e comportamento de rolagem otimizado, mas não tem uma ação associada a um item de lista. Normalmente, essas interfaces usam o item de lista apenas para agrupar elementos e garantir que eles rolem como um conjunto.
Esse tipo de interface do usuário tende a ser muito mais complicado do que os exemplos anteriores, com muitos elementos aninhados nos quais o usuário pode agir.
Para obter essa interface do usuário, defina as seguintes propriedades em sua lista:
- SelectionMode to None.
- IsItemClickEnabled para false.
- IsFocusEngagementEnabled como true.
<ListView SelectionMode="None" IsItemClickEnabled="False" >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsFocusEngagementEnabled" Value="True"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Quando os itens de lista não executam uma ação, recomendamos essa orientação para lidar com a navegação com um gamepad ou teclado.
Gamepad
Quando a entrada é de um gamepad, forneça esta experiência do usuário:
- No item da lista, a tecla direcional para baixo foca no próximo item da lista.
- No Item de Lista, a tecla esquerda/direita não exerce nenhuma função, ou se houver um elemento de interface do usuário focalizável à direita da Lista, o foco é colocado ali.
- No Item de Lista, o botão 'A' coloca o foco na UI aninhada com prioridade de cima/baixo e esquerda/direita.
- Enquanto estiver dentro da interface de usuário hierárquica, siga o modelo de navegação do Foco XY. O foco só pode navegar pela interface do usuário aninhada dentro do item de lista atual até que o usuário pressione o botão 'B', que retorna o foco para o item de lista.
Keyboard
Quando a entrada é de um teclado, essa é a experiência que o usuário obtém:
- No Item de Lista, a tecla de seta para baixo coloca o foco no próximo Item de Lista.
- No Item de Lista, pressionar as teclas esquerda/direita não realiza nenhuma operação.
- No Item de Lista, pressionar a tecla tab coloca o foco na próxima parada de tabulação entre o item de interface do usuário aninhado.
- Ao pressionar a tecla Tab em um dos itens de interface do usuário aninhados, percorre-se os itens de interface nesta ordem de tabulação. Uma vez que todos os itens de UI aninhados foram percorridos, ele foca no próximo controle na ordem de tabulação após o ListView.
- Shift+Tab se comporta na direção inversa do comportamento da guia.
Example
Este exemplo mostra como implementar uma UI aninhada em que os itens da lista executam uma ação.
<ListView SelectionMode="None" IsItemClickEnabled="True"
ChoosingItemContainer="listview1_ChoosingItemContainer"/>
private void OnListViewItemKeyDown(object sender, KeyRoutedEventArgs e)
{
// Code to handle going in/out of nested UI with gamepad and remote only.
if (e.Handled == true)
{
return;
}
var focusedElementAsListViewItem = FocusManager.GetFocusedElement() as ListViewItem;
if (focusedElementAsListViewItem != null)
{
// Focus is on the ListViewItem.
// Go in with Right arrow.
Control candidate = null;
switch (e.OriginalKey)
{
case Windows.System.VirtualKey.GamepadDPadRight:
case Windows.System.VirtualKey.GamepadLeftThumbstickRight:
var rawPixelsPerViewPixel = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
GeneralTransform generalTransform = focusedElementAsListViewItem.TransformToVisual(null);
Point startPoint = generalTransform.TransformPoint(new Point(0, 0));
Rect hintRect = new Rect(startPoint.X * rawPixelsPerViewPixel, startPoint.Y * rawPixelsPerViewPixel, 1, focusedElementAsListViewItem.ActualHeight * rawPixelsPerViewPixel);
candidate = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Right, hintRect) as Control;
break;
}
if (candidate != null)
{
candidate.Focus(FocusState.Keyboard);
e.Handled = true;
}
}
else
{
// Focus is inside the ListViewItem.
FocusNavigationDirection direction = FocusNavigationDirection.None;
switch (e.OriginalKey)
{
case Windows.System.VirtualKey.GamepadDPadUp:
case Windows.System.VirtualKey.GamepadLeftThumbstickUp:
direction = FocusNavigationDirection.Up;
break;
case Windows.System.VirtualKey.GamepadDPadDown:
case Windows.System.VirtualKey.GamepadLeftThumbstickDown:
direction = FocusNavigationDirection.Down;
break;
case Windows.System.VirtualKey.GamepadDPadLeft:
case Windows.System.VirtualKey.GamepadLeftThumbstickLeft:
direction = FocusNavigationDirection.Left;
break;
case Windows.System.VirtualKey.GamepadDPadRight:
case Windows.System.VirtualKey.GamepadLeftThumbstickRight:
direction = FocusNavigationDirection.Right;
break;
default:
break;
}
if (direction != FocusNavigationDirection.None)
{
Control candidate = FocusManager.FindNextFocusableElement(direction) as Control;
if (candidate != null)
{
ListViewItem listViewItem = sender as ListViewItem;
// If the next focusable candidate to the left is outside of ListViewItem,
// put the focus on ListViewItem.
if (direction == FocusNavigationDirection.Left &&
!listViewItem.IsAncestorOf(candidate))
{
listViewItem.Focus(FocusState.Keyboard);
}
else
{
candidate.Focus(FocusState.Keyboard);
}
}
e.Handled = true;
}
}
}
private void listview1_ChoosingItemContainer(ListViewBase sender, ChoosingItemContainerEventArgs args)
{
if (args.ItemContainer == null)
{
args.ItemContainer = new ListViewItem();
args.ItemContainer.KeyDown += OnListViewItemKeyDown;
}
}
// DependencyObjectExtensions.cs definition.
public static class DependencyObjectExtensions
{
public static bool IsAncestorOf(this DependencyObject parent, DependencyObject child)
{
DependencyObject current = child;
bool isAncestor = false;
while (current != null && !isAncestor)
{
if (current == parent)
{
isAncestor = true;
}
current = VisualTreeHelper.GetParent(current);
}
return isAncestor;
}
}
Windows developer