Что такого особенного в Generic.xaml?


153

Я пытался выяснить, как организовать мои файлы ResourceDictionary для повторного использования и обмена с другими членами моей команды.

Я продолжаю сталкиваться с «Generic.xaml», но если я смотрю на MSDN Generic.xaml или просто делаю поиск в Google, я, похоже, получаю только сообщения в блогах и вопросы на форуме, которые случайно упоминают об этом - я не могу наткнуться на что-нибудь действительно авторитетное и понятное.

В чем разница между Generic.xaml и MyRandomlyNamedResourceDictionary.xaml? Похоже, в любом случае, я должен ссылаться на ResourceDictionaries, хранящиеся в библиотеках с атрибутом Source. Например,:

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

Так какое же преимущество дает Generic.xaml? Имеет ли это какое-либо назначение, если я не пытаюсь придать своему приложению несколько «взглядов» (т. Е. Если у меня есть только одна тема)?


6
Вам не нужно объединять словарь generic.xaml с вашим кодом, если вы используете его с пользовательскими элементами управления (в отличие от пользовательских элементов управления).
Вечный 21

Ответы:


152

Каждый элемент управления в WPF имеет стиль по умолчанию, который обеспечивает, помимо прочего, элемент управления по умолчанию ControlTemplate. WPF ищет стиль по умолчанию в специальном словаре ресурсов в папке Темы в той же сборке, что и элемент управления. Ключ для стиля по умолчанию предоставляется Control.DefaultStyleKeyсвойством зависимости, значение по умолчанию которого переопределяется в каждом подклассе элемента управления.

Название словаря ресурсов зависит от текущей темы Windows, например, в Vista, в которой используется тема Aero, словарь называется Aero.NormalColor.xaml, в XP, в которой используется тема по умолчанию, это Luna.NormalColor.xaml. Если стиль не найден в словаре темы, он ищет в Generic.xaml, т.е. для элементов управления, внешний вид которых не зависит от темы.

Это относится только к любым пользовательским элементам управления, которые вы определили, т. Е. К классам, производным от Control, прямо или косвенно. Вы можете изменить стиль по умолчанию для стандартного элемента управления, наследуя его и вызывая DefaultStyleKeyProperty.OverrideMetadataстатический конструктор, но затем вам необходимо предоставить полный стиль, включая ControlTemplate.

Обратите внимание, что вы можете указать WPF искать во внешней сборке ваш стиль по умолчанию, используя атрибут ThemeInfo. Внешняя сборка должна называться <YourAssembly >. <ThemeName >.dll, например PresententationFramework.Aero.dll.


Спасибо, Фил. Итак, вы говорите, что если бы я просто хотел предоставить новый ControlTemplate для обычного элемента управления Button (т.е. не писать свой собственный специальный класс, производный от Button), это не будет считаться частью «темы»?
devuxer

Да, если вы просто хотите изменить шаблон или изменить стиль стандартного элемента управления, то вы используете обычный элемент Resources на уровне UserControl / Window / Application / Wh независимо от уровня. Вы можете использовать стиль с неявным ключом ( msdn.microsoft.com/en-us/library/… ), чтобы изменить все элементы управления определенного типа.
Фил Девани

@Zaheylu Это работает сейчас (я думаю, что MS обновляла свои документы)
Алан Макби - MSFT

104

Чтобы generic.xamlфайл (без учета регистра) был чем-то особенным, должны быть выполнены два условия:

  • Он должен находиться в папке «Темы» в проекте
  • Сборка должна быть помечена ThemeInfoAttribute(обычно в AssemblyInfo.cs)

Затем он служит местом поиска по умолчанию для любых стилей по умолчанию, которые вы хотите применить к своим элементам управления. Также обратите внимание, что для того, чтобы стиль был стилем по умолчанию, он должен объявить как TargetType, так и x: Key как тип элемента управления, который должен быть стилизован.

Если вы хотите добавить в приложение целые темы и переключение тем, что выполняется с помощью некоторого кодирования, этот метод просто определяет словарь ресурсов по умолчанию.


3
Можете ли вы уточнить, что вы подразумеваете под "стилями по умолчанию"? Означает ли это, что все кнопки автоматически приобретут стиль, для которого TargetType имеет значение «Button»? Или мне все же нужно ссылаться на него x:Keyв письменном виде <Button Style="{StaticResource MyButtonStyle}" />? Что произойдет, если ResourceDictionary содержит более одного стиля, для которого TargetType имеет значение «Button»? Спасибо.
devuxer

3
Еще один вопрос, который поможет мне в этом разобраться: Generic.xaml - это WPF-эквивалент CSS-файла, который определяет внешний вид различных элементов по умолчанию, например h1 {color:#00ff00}?
devuxer

3
Да, стиль по умолчанию будет применяться без явной ссылки на ключ, и два идентичных стиля приведут к ошибке, что в словаре есть два идентичных ключа. И да, вы могли бы думать об этом так, относительно поведения по умолчанию.
Кенан ЭК

3
Просто хочу добавить, что, хотя верно и то, что существуют специальные ограничения для самого файла generic.xaml, словарная запись в generic.xaml может быть объединенным словарем, чьи записи могут ссылаться на что угодно.
Tormod
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.