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.
Interface do usuário aninhada é uma interface do usuário (IU) que expõe controles aninhados acionáveis colocados dentro de um contêiner que também pode 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 aninhada, 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 interface do usuário 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.
- Interface do usuário aninhada refere-se a elementos da interface do usuário em um item de lista nos quais o usuário pode executar uma ação separadamente da execução da ação no item de lista em si.
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 formas de interface do usuário aninhada funcionam muito bem com um método de entrada, mas talvez não funcionem 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 as ações secundárias na interface do usuário de foco para otimizar para 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 interface do usuário aninhada funciona 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.
Manipulação da interface do usuário aninhada
Quando você tiver mais de uma ação aninhada no item de lista, recomendamos estas orientações para manipular 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 de lista com elementos aninhados aceitar ações como invocar, seleção (única ou vários) ou operações de arrastar e soltar, recomendamos estas técnicas de seta para navegar pelos elementos da interface do usuário aninhada.
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 tecla de direção para a direita não funciona ou, se houver um elemento de interface do usuário focalizável à direita da lista, coloca o foco nela.
- 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 de direção para a esquerda não funciona ou, se houver um elemento de interface do usuário focalizável à direita da lista, coloca o foco nela.
- 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 tecla de direção para a 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.
- De C, a tecla tab coloca o foco no próximo elemento de interface do usuário focalizável na ordem de tabulação.
- De C, shift+tecla tab coloca o foco em B.
- De B, as teclas shift + tab ou a tecla de seta para a esquerda colocam o foco em A.
- De A, as teclas shift + tab colocam o foco no próximo elemento de interface do usuário focalizável na ordem de tabulação inversa.
- 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, as teclas shift e tab colocam o foco em C.
Para chegar a 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 como 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.
- Do item de lista, a tecla para a esquerda/direita não funciona ou, se houver um elemento de interface do usuário focalizável à direita da lista, coloca o foco nela.
- Do item de lista, o botão 'A' coloca o foco na interface do usuário aninhada na ordem de prioridade de cima para baixo, da esquerda para a direita.
- Enquanto estiver dentro da interface de usuário aninhada, siga o modelo de navegação de foco XY. O foco só pode navegar pela interface do usuário aninhada contida no item de lista atual até que o usuário pressione o botão 'B', que volta 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.
- Do item de lista, pressionar a tecla para a esquerda/direita não executa qualquer operação.
- Do item da lista, pressionar a tecla tab coloca o foco na próxima parada de tabulação entre o item da interface do usuário aninhada.
- De um dos itens da interface do usuário aninhada, pressionar a tecla tab percorre os itens da interface do usuário aninhada na ordem de tabulação. Depois que todos os itens da interface do usuário aninhada são percorridos, coloca o foco no próximo controle na ordem de tabulação após 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