2013-07-30 3 views
4

У меня есть следующая ситуация (упрощенный):Стандартные стили WPF и UserControls - лучшие практики?

В моей ResourceDictionary я определил пару именованных стилей для этикетки:

<Style 
    x:Key="sNormalLabel" 
    TargetType="Label" > 
    <Setter Property="FontFamily" Value="Verdana" /> 
    <Setter Property="FontSize" Value="12" /> 
    <!-- ... --> 
</Style> 
<Style 
    x:Key="sHeaderLabel" 
    TargetType="Label" 
    BasedOn="{StaticResource sNormalLabel}" > 
    <Setter Property="FontSize" Value="16" /> 
</Style> 

И тогда я сделать один из них по умолчанию с помощью ссылки его BasedOn , в стиле, который не имеет ключа:

<!-- Apply Normal label automatically --> 
<Style 
    TargetType="Label" 
    BasedOn="{StaticResource sNormalLabel}" /> 

Я думал, что это очень удобно, чтобы автоматически применить нормальный стиль этикетки, что, как я знаю, что если в будущем наша проектная группа решает пойти с Wingdings или somethi ng, его очень легко изменить для всего приложения (фактически все приложения, которые имеют один и тот же ResourceDictionary).

Создание UserControl Я хочу, чтобы добавить ярлык в верхней части со стилем sHeaderLabel, так как она идет применяю

Style={StaticResource sHeaderLabel} 

в UserControl XAML, и все выглядит нормально в конструкторе.

Однако, когда я добавляю UserControl в MainWindow, метка заголовка возвращается к стилю sNormalLabel (автоматически применяется).

Я предполагаю, что это связано с порядком, в котором применяются стили, UserControl оформляется MainWindow после его создания, а стиль sHeaderLabel перезаписывается автоматическим.

Это оставляет меня пару вопросов без ответа:

  1. Это редкость, и в отличие от лучшей практики использования автоматически применяются стили, как я сделал? Я думал, что это очень практично, но, возможно, это неправильный путь.
  2. Можно ли каким-либо образом исключить определенные элементы управления из-за применения этих автоматических стилей? Единственный способ, с помощью которого я могу думать, - расширить Label с помощью HeaderLabel и применить другой ключ ресурса, чтобы HeaderLabel автоматически применял к нему стиль sHeaderLabel. Есть ли другой путь?

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

EDIT: Интересно, что я только понял, что вижу только эти проблемы со свойствами Font *. Настройка кистей переднего плана/фона по-разному в стандартном/верхнем стиле оставляет метку в UserControl (которая имеет стиль sHeaderLabel) с цветом CORRECT. Настройка FontWeight, выделенная полужирным шрифтом в sHeaderLabel, не имеет никакого эффекта.

Я также создал стили TextBox таким же образом, с стилем HeaderTExtBox, и я тоже не вижу проблемы там, только с ярлыками.

Cheers!

./Fredrik

+0

Если вы исключаете элементы управления от применения стилей, вы, вероятно, не должны применять стиль ко всему, в первую очередь. Хотя я не уверен, чтобы дать ответ на этот вопрос, я стараюсь избегать автоматических стилей, поскольку они иногда могут неожиданно запутываться со встроенными 'DataTemplates', содержащими эти типы. Например, если вы не знаете, содержит ли кнопка «Ярлык» или «TextBlock», вы не можете быть уверены, как это повлияет на стиль авто. –

+0

Привет, спасибо за ваш ответ! Идея состояла в том, чтобы иметь общие элементы управления, автоматически соответствующие заранее определенному стандарту. Я слишком часто создавал внешний вид Forms 'DataGridView' WAAAY, чтобы не любить идею определения стандарта один раз и применять его повсеместно. Тогда все ситуации разные, и если мне придется входить и переопределять стиль или даже исключать определенный элемент управления в некоторых случаях, я более чем счастлив сделать это. Но то, что вы говорите о неожиданных побочных эффектах, имеет прекрасный смысл! Я уже вижу, что элемент управления Microsoft Ribbon делает то, что он не использовал. – Fredrik

ответ

1

Хорошая практика может заключаться в том, чтобы избежать применения базовых автоматических стилей к стандартным типам, поскольку результаты могут быть непредсказуемыми.

В ответ на то, что в конечном итоге стало вашей проблемой, хорошим примером является применение стиля к TextBlock. Этот стиль будет применяться к Label, Button и любому другому элементу управления в любом месте фреймворка, который может содержать TextBlock, который не отменяет стиль, который вы устанавливаете.

Вы не можете «отменить» стиль при применении ко всем экземплярам типа, вы можете переопределить стиль только с помощью нового стиля. Если вы не сможете точно предсказать все в своем приложении, что это повлияет (например, стиль управления, который вы сделали), вам следует избегать использования автоматического стиля в пользу установки x:Key.

+0

Hi Will, Мое предположение относительно порядка, в котором применяются стили, было неправильным, поэтому необходимость «отмены применения» стиля ошибочна. Я могу только согласиться с вами, тем более, что я могу переопределить стиль любого элемента управления, который я явно использую, но не дочерние элементы управления этих элементов управления. Будем надеяться, что MS предоставит нам систему правил на основе xpath, чтобы предоставить нам полный контроль над стилем наших приложений. Приветствия! – Fredrik

0

Ну, я понял это.

У меня также был стиль по умолчанию для TextBlock и удаление этого глобального исправления.Согласно MSDN, Label и TextBlock не имеют отношения по наследованию, а TextBlock делает не от Control, что интересно.

Возможно Label использует TextBlock внутренне для рендеринга, я не знаю, но явно стиль по умолчанию TextBlock влиял на поведение Label.

+0

Да, «Ярлык» содержит «TextBlock». Было бы неплохо прочитать http://stackoverflow.com/questions/59099/what-is-the-difference-between-the-wpf-textblock-element-and-label-control, чтобы узнать различия, Josh В приведенной статье Смита очень хорошо для понимания различий. –

+0

Я также дал ответ, в основном сочетание того, что ваша проблема в итоге сочеталась с моим оригинальным комментарием. –

Смежные вопросы