Partilhar via


Modelos de controlo

Você pode personalizar a estrutura visual e o comportamento visual de um controle criando um modelo de controle na estrutura XAML. Os controles têm muitas propriedades, como Background, Foreground e FontFamily, que você pode definir para especificar diferentes aspetos da aparência do controle. Mas as alterações que você pode fazer definindo essas propriedades são limitadas. Você pode especificar personalizações adicionais criando um modelo usando a classe ControlTemplate . Aqui, mostramos como criar um ControlTemplate para personalizar a aparência de um CheckBox controle.

APIs importantes: classe ControlTemplatepropriedade Control.Template

Exemplo de modelo de controle personalizado

Por padrão, um controle CheckBox coloca seu conteúdo (a cadeia de caracteres ou objeto ao lado da CheckBox) à direita da caixa de seleção, e uma marca de seleção indica que um usuário selecionou a CheckBox. Essas características representam a estrutura visual e o comportamento visual da CheckBox.

Aqui está uma CheckBox usando o ControlTemplate padrão mostrado nos estados , e .

modelo de caixa de seleção padrão

Você pode alterar essas características criando um ControlTemplate para a CheckBox. Por exemplo, se você quiser que o conteúdo da caixa de seleção fique abaixo da caixa de seleção e quiser usar um X para indicar que um usuário marcou a caixa de seleção. Você especifica essas características no ControlTemplate do CheckBox.

Para usar um modelo personalizado com um controle, atribua o ControlTemplate à propriedade Template do controle. Aqui está um CheckBox usando um ControlTemplate chamado CheckBoxTemplate1. Mostramos a Extensible Application Markup Language (XAML) para o ControlTemplate na próxima seção.

<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>

Veja como essa CheckBox fica nos estados Unchecked, Checked e Indeterminate depois de aplicarmos o nosso modelo.

modelo de caixa de seleção personalizado

Especificar a estrutura visual de um controle

Quando você cria um ControlTemplate, você combina objetos FrameworkElement para criar um único controle. Um ControlTemplate deve ter apenas um FrameworkElement como seu elemento raiz. O elemento raiz geralmente contém outros objetos FrameworkElement . A combinação de objetos compõe a estrutura visual do controle.

Este XAML cria um ControlTemplate para um CheckBox que especifica que o conteúdo do controlo está abaixo da caixa de seleção. O elemento raiz é um Border. O exemplo especifica o Caminho para criar um X que indica que um utilizador selecionou a CheckBoxe uma Elipse que indica um estado indeterminado. Observe que a Opacidade está definida como 0 no Caminho e na Elipse para que, por padrão, nenhum apareça.

Um TemplateBinding é uma associação especial que vincula o valor de uma propriedade num modelo de controlo ao valor de alguma outra propriedade exposta no controlo modelado. TemplateBinding só pode ser usado dentro de uma definição ControlTemplate em XAML. Consulte extensão de marcação TemplateBinding para obter mais informações.

Observação

A partir do Windows 10, versão 1809 (SDK 17763), pode usar extensões de marcação x:Bind nos locais onde utiliza TemplateBinding. Consulte extensão de marcação TemplateBinding para obter mais informações.

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

Especificar o comportamento visual de um controle

Um comportamento visual especifica a aparência de um controle quando ele está em um determinado estado. O controlo CheckBox tem 3 estados de verificação: Checked, Uncheckede Indeterminate. O valor da propriedade IsChecked determina o estado da CheckBox e seu estado determina o que aparece na caixa.

Esta tabela lista os valores possíveis de IsChecked, os estados correspondentes da CheckBox e a aparência da CheckBox.

"IsChecked" valor CheckBox estado aparência da caixa de seleção
verdadeiro Checked Contém um "X".
falso Unchecked Vazio.
nulo Indeterminate Contém um círculo.

Você especifica a aparência de um controle quando ele está em um determinado estado usando objetos VisualState . Um VisualState contém um Setter ou Storyboard que altera a aparência dos elementos no ControlTemplate. Quando o controle entra no estado especificado pela propriedade VisualState.Name, as alterações de propriedade no Setter ou Storyboard são aplicadas. Quando o controle sai do estado, as alterações são removidas. Você adiciona objetos VisualState a objetos VisualStateGroup. Você adiciona objetos VisualStateGroup à propriedade anexada VisualStateManager.VisualStateGroups, que é definida na raiz do FrameworkElement do ControlTemplate.

Este XAML mostra os objetos VisualState para os estados Checked, Unchecked e Indeterminate. O exemplo define a propriedade anexada VisualStateManager.VisualStateGroups na Border, que é o elemento raiz do ControlTemplate. O VisualState especifica que o de Opacidade do Path do chamado (que mostramos no exemplo anterior) é 1. O VisualState especifica que o de opacidade do Ellipse chamado é 1. O VisualState não tem Setter ou Storyboard, portanto, a CheckBox retorna à aparência padrão.

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CheckStates">
                <VisualState x:Name="Checked">
                    <VisualState.Setters>
                        <Setter Target="CheckGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
                <VisualState x:Name="Unchecked"/>
                <VisualState x:Name="Indeterminate">
                    <VisualState.Setters>
                        <Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

Para entender melhor como objetos VisualState funcionam, considere o que acontece quando o CheckBox passa do estado Unchecked para o estado Checked, depois para o estado Indeterminate e então de volta para o estado Unchecked. Aqui estão as transições.

Transição de Estado O que acontece Aparência da caixa de seleção quando a transição for concluída
De Unchecked a Checked. O Setter valor do CheckedVisualState é aplicado, portanto, a Opacidade de CheckGlyph é 1. Um X é exibido.
De Checked a Indeterminate. O Setter valor do IndeterminateVisualState é aplicado, portanto, a Opacidade de IndeterminateGlyph é 1. O Setter valor do VisualState é removido, portanto, o de opacidade de é 0. Um círculo é exibido.
De Indeterminate a Unchecked. O valor do Setter do IndeterminateVisualState é removido, portanto, a Opacidade de IndeterminateGlyph é 0. Nada é exibido.

 Para saber mais sobre como criar estados visuais para controles e, em particular, como usar a classe Storyboard e os tipos de animação, veja Animações com storyboard para estados visuais.

Use ferramentas para trabalhar com temas facilmente

Uma maneira rápida de aplicar temas aos seus controles é clicar com o botão direito do mouse em um controle na Estrutura de Tópicos do Documento do Microsoft Visual Studio e selecionar Editar Tema ou Editar Estilo (dependendo do controle em que você está clicando com o botão direito do mouse). Em seguida, pode aplicar um tema existente selecionando Aplicar Recurso ou definir um novo selecionando Criar Vazio.

Controlos e acessibilidade

Quando você cria um novo modelo para um controle, além de possivelmente alterar o comportamento e a aparência visual do controle, você também pode estar alterando como o controle se representa para estruturas de acessibilidade. O aplicativo do Windows oferece suporte à estrutura de automação da interface do usuário da Microsoft para acessibilidade. Todos os controles padrão e seus modelos têm suporte para tipos e padrões de controle comuns de Automação da Interface do Usuário que são apropriados para a finalidade e função do controle. Esses tipos e padrões de controle são interpretados por clientes de automação da interface do usuário, como tecnologias assistenciais, e isso permite que um controle seja acessível como parte de uma interface do usuário de aplicativo acessível maior.

Para separar a lógica de controlo básica e também para satisfazer alguns dos requisitos de arquitetura da Automação da Interface de Utilizador, as classes de controlo incluem o seu suporte de acessibilidade numa classe distinta, denominada peer de automação. Os pares de automatização, por vezes, interagem com os modelos de controlo porque esperam que certas partes nomeadas existam nesses modelos, permitindo assim que funcionalidades, como a ativação de tecnologias assistivas para acionar ações de botões, sejam possíveis.

Ao criar um controlo personalizado completamente novo, às vezes, também podes querer criar um novo peer de automação para o acompanhar. Para mais informações, veja Pares de automação personalizados.

Saiba mais sobre o modelo padrão de um controle

Os tópicos que documentam os estilos e modelos para controles XAML mostram trechos do mesmo XAML inicial que você veria se usasse o Editar Tema ou Editar Estilo técnicas explicadas anteriormente. Cada tópico lista os nomes dos estados visuais, os recursos de tema usados e o XAML completo para o estilo que contém o modelo. Os tópicos podem ser uma orientação útil se você já tiver começado a modificar um modelo e quiser ver a aparência do modelo original ou verificar se o novo modelo tem todos os estados visuais nomeados necessários.

Recursos de tema em modelos de controle

Para alguns atributos, pode ter notado, nos exemplos XAML, referências de recursos que usam a extensão de marcação {ThemeResource} . Esta é uma técnica que permite que um único modelo de controle use recursos que podem ser valores diferentes, dependendo de qual tema está ativo no momento. Isso é particularmente importante para pincéis e cores, porque o principal objetivo dos temas é permitir que os usuários escolham se querem um tema escuro, claro ou de alto contraste aplicado ao sistema em geral. Os aplicativos que usam o sistema de recursos XAML podem usar um conjunto de recursos apropriado para esse tema, para que as opções de tema na interface do usuário de um aplicativo reflitam a escolha de tema de todo o sistema do usuário.

Obter o código de exemplo