O que há de tão especial no Generic.xaml?

153

Eu tenho tentado descobrir como organizar meus arquivos ResourceDictionary para reutilização e compartilhamento com outros membros da minha equipe.

Eu continuo encontrando o "Generic.xaml", mas se eu procurar no Generic.xaml no MSDN ou apenas faço uma pesquisa no Google, apenas recebo postagens de blog e perguntas do fórum que mencionam isso - não consigo encontre algo realmente autoritário e claro.

Qual é a diferença entre Generic.xaml e MyRandomlyNamedResourceDictionary.xaml? Parece que de qualquer maneira, eu tenho que fazer referência a ResourceDictionaries armazenados em bibliotecas com o atributo Source. Por exemplo,:

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml"
</Application.Resources>

Então, que vantagem o Generic.xaml oferece exatamente? Isso tem algum objetivo se eu não estiver tentando fornecer ao meu aplicativo várias "aparências" (ou seja, se eu tiver apenas um tema)?

devuxer
fonte
6
Não é necessário mesclar o dicionário generic.xaml no seu código, se você o estiver usando com controles personalizados (ao contrário dos controles do usuário).
Eternal21

Respostas:

152

Todo controle no WPF possui um estilo padrão que fornece, entre outras coisas, o padrão do controle ControlTemplate. O WPF procura o estilo padrão em um dicionário de recursos especial na pasta Temas no mesmo assembly que o controle. A chave para o estilo padrão é fornecida pela Control.DefaultStyleKeypropriedade dependency, cujo valor padrão é substituído em cada subclasse de Control.

O nome do dicionário de recursos depende do tema atual do Windows, por exemplo, no Vista, usando o tema Aero, o dicionário é chamado Aero.NormalColor.xaml, no XP, usando o tema padrão, Luna.NormalColor.xaml. Se o estilo não for encontrado no dicionário de temas, ele procurará em Generic.xaml, ou seja, controles cuja aparência não depende do tema.

Isso se aplica apenas a quaisquer controles personalizados que você definiu, ou seja, classes derivadas de Control, direta ou indiretamente. Você pode alterar o estilo padrão de um controle padrão derivando dele e chamando DefaultStyleKeyProperty.OverrideMetadatao construtor estático, mas precisará fornecer o estilo completo, incluindo ControlTemplate.

Observe que você pode dizer ao WPF para procurar em um assembly externo o seu estilo padrão usando o atributo ThemeInfo. A montagem externa deve ter o nome <YourAssembly >. <ThemeName >.dll, por exemplo, PresententationFramework.Aero.dll.

Phil Devaney
fonte
Obrigado, Phil. Então você está dizendo que se eu apenas quisesse fornecer um novo ControlTemplate para um controle normal de Button (ou seja, não escrever minha própria classe especial que deriva de Button), isso não seria considerado parte de um "tema"?
Devuxer 05/08/09
Sim, se você deseja apenas refazer o modelo ou refazer o estilo de um controle padrão, use o elemento normal de Recursos no nível UserControl / Window / Application / Whatever. Você pode usar um estilo com uma chave implícita ( msdn.microsoft.com/en-us/library/… ) para alterar todos os controles de um determinado tipo.
22440 Phil Devaney
@Zaheylu ele está trabalhando agora (acho que MS estava atualizando seus docs)
Alan McBee - MSFT
104

Para que um generic.xamlarquivo (sem distinção entre maiúsculas e minúsculas) seja algo especial, duas condições devem ser atendidas:

  • Ele deve estar na pasta sub-raiz de Temas no projeto
  • A montagem deve ser marcada com ThemeInfoAttribute(geralmente em AssemblyInfo.cs)

Em seguida, ele serve como o local de pesquisa padrão para todos os estilos padrão que você deseja aplicar aos seus controles. Observe também que, para um estilo ser o padrão, ele deve declarar o TargetType e x: Key como o Tipo de controle a ser estilizado.

Se você deseja adicionar temas inteiros e alternância de temas ao seu aplicativo, isso é feito com alguma codificação, essa técnica apenas define o dicionário de recursos padrão.

Kenan EK
fonte
3
Você pode esclarecer o que você quer dizer com "estilos padrão"? Isso significa que todos os botões adotariam automaticamente um estilo cujo TargetType seja "Button"? Ou ainda preciso fazer referência ao x:Keyescrevendo <Button Style="{StaticResource MyButtonStyle}" />? O que acontece se o ResourceDictionary contiver mais de um estilo cujo TargetType seja "Button"? Obrigado.
Devuxer 04/08/09
3
Outra pergunta para me ajudar a entender isso: Generic.xaml é o equivalente do WPF a um arquivo CSS que definiu a aparência padrão de diferentes elementos, por exemplo h1 {color:#00ff00},?
Devuxer 04/08/09
3
Sim, o estilo padrão se aplicaria sem referenciar explicitamente a chave e dois estilos idênticos causariam o erro de que existem duas chaves idênticas no dicionário. E sim, você pode pensar dessa maneira, em relação ao comportamento padrão.
Kenan EK
3
Só queria acrescentar que, embora seja verdade que existem restrições especiais no arquivo generic.xaml, a entrada do dicionário dentro do generic.xaml pode ser um dicionário mesclado cujas entradas podem fazer referência a qualquer coisa.
Tormod