Нужен совет как поменять цвета

Я создаю приложение WPF, которое будет работать на портативных компьютерах, установленных в полицейских машинах. В приложении должен быть «Ночной режим», который будет использовать более темные цвета, чтобы меньше нагружать глаза ночью.

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

Я создал перечисление под названием TimesOfDay. В перечислении есть два значения: DayTime и NightTime. Каждый элемент управления имеет DepenencyProperty, называемый TimeOfDay, типа перечисления TimesOfDay. На главном экране есть кнопка, которую вы нажимаете, чтобы изменить значение свойства TimeOfDay. Когда вы нажимаете кнопку, значение свойства TimeOfDay меняется между двумя значениями.

Я все еще новичок в WPF, поэтому я не уверен, как это сделать на стороне Xaml. Я думаю, что мне нужно создать два именованных стиля, например, один называется DayStyle, а другой - NightStyle. Затем мне нужно где-то добавить триггеры, чтобы изменить стиль, применяемый к элементам управления при изменении свойства TimeOfDay. Это правильно?

Могу ли я просто изменить цвета фона и переднего плана элементов управления по типу? Могу я сделать это по имени элемента?

Я очень не уверен во всем этом. Любая помощь будет оценена.

Тони


person Tony Vitabile    schedule 22.03.2012    source источник


Ответы (3)


Каждый элемент управления имеет свойство DepenencyProperty с именем TimeOfDay типа перечисления TimesDay.

Не делайте этого, просто создайте две полные темы в отдельных ResourceDictionaries, которые затем можно переключить с помощью MergedDictionaries в Application.Resources. Нет необходимости размещать дневную информацию на элементах управления.

person H.B.    schedule 22.03.2012
comment
Это выглядит интересно, и это должно быть несложно. Он работает так, как я сейчас устанавливаю цвета (я определил число Brushes в моем файле app.xaml, на который я ссылаюсь, используя предложения DynamicResource, как в примере). Моя проблема в том, что я не хочу, чтобы ResourceDictionaries находился в файлах на диске. Могу ли я встроить их как ресурсы в исполняемый файл и получить их оттуда? - person Tony Vitabile; 22.03.2012
comment
@TonyVitabile: Наверное, сам еще не пробовал, этот вопрос может будь полезным, мэйбе есть и другие. - person H.B.; 22.03.2012
comment
Я поменял только пару цветов, но механизм у меня заработал. И ResourceDictionaries встраиваются как ресурсы в исполняемый файл. Теперь мне просто нужно установить все цвета для ночного времени и настроить все свойства, в которых я забыл использовать одну из моих кистей. Спасибо! - person Tony Vitabile; 22.03.2012
comment
Это отлично работает в моем главном окне, но есть проблема. У меня есть специальный класс Dialog, в котором я реализовал все это, но он не меняет цвета. В шаблоне класса Dialog используется тот же DynamicResources, что и в моем главном окне. Почему в диалоговом окне по-прежнему отображаются дневные цвета, когда главное окно находится в ночном режиме? - person Tony Vitabile; 24.03.2012
comment
Ничего, я понял. Мне пришлось привязать свойство TimeOfDay в диалоговом окне к свойству TimeOfDay в главном окне, и тогда все заработало. - person Tony Vitabile; 24.03.2012
comment
@TonyVitabile: Если бы вы сделали то, что я предлагал, свойства TimeOfDay больше не было бы o.O. - person H.B.; 24.03.2012

Следуйте этому руководству: http://weblogs.asp.net/psheriff/archive/2009/12/01/load-resource-dictionaries-at-runtime-in-wpf.aspx

  1. Создайте различные файлы ресурсов xaml, но убедитесь, что файл не компилируется и вместо этого копируется в каталог bin.
  2. Украсьте элементы управления xaml DynamicResources.
  3. Загрузите свои ресурсы через код.

По сути, вы пытаетесь «скинуть» свое приложение. Код, загружаемый в ваш файл ресурсов, может использовать перечисление TimeOfDay.

Если вы хотите, чтобы это было автоматизировано, вы можете даже иметь некоторый статический класс, у которого есть таймер для автоматической попытки изменить ресурс и установить таймер при запуске приложения. :)

person myermian    schedule 22.03.2012

Я бы не стал дублировать стиль, потому что ненавижу дублированный код ... Этого легко добиться с помощью триггера в ControlTemplate:

<Trigger Property="TimeOfDay" Value="NightTime">
    <Setter TargetName="someControl" Property="Background" Value="Black" />
    <Setter TargetName="someOtherControl" Property="ForeGround" Value="Yellow" />
    ...
</Trigger>

Другой вариант - использовать описанную мной технику здесь. Таким образом, вам даже не нужно указывать TimeOfDay информацию на самом элементе управления, это может быть внешнее свойство.

person Thomas Levesque    schedule 22.03.2012
comment
Прикрепленный подход к собственности в вашем сообщении в блоге выглядит интересно. Я мог бы попробовать. - person Tony Vitabile; 22.03.2012
comment
Я должен не согласиться с этим, поскольку я ненавижу дублированный код, в его случае было бы намного проще поддерживать 2 стиля и запускать их на уровне приложения, чем иметь триггеры в каждом элементе управления ... у него, вероятно, не так много цветов в любом случае в его приложении, поэтому выполнение того, что вы делаете, на самом деле будет означать больше дублированного кода, чем запуск нескольких цветов на уровне приложения - person David; 22.03.2012
comment
Я начал пытаться использовать предложение Томаса о применении триггеров к шаблону управления. Но я не понимаю, куда мне их положить? Большинство моих элементов управления - это UserControls, а не пользовательские элементы управления. У меня есть несколько из них, и я полагаю, что смогу преобразовать все заново, но нужно ли это делать? - person Tony Vitabile; 22.03.2012
comment
@TonyVitabile, с триггерами UserControls пользоваться будет не очень удобно. Попробуйте вместо этого использовать мое решение на основе прикрепленных свойств - person Thomas Levesque; 22.03.2012
comment
@ThomasLevesque, компилятор не позволяет мне использовать {TemplateBinding} в UserControl Xaml. Как, например, привязать значение свойства Background в TextBox к свойству в моем классе ThemeProperties? - person Tony Vitabile; 22.03.2012
comment
@TonyVitabile, если вы сделали свойство ambient с флагом Inherits, вы можете использовать обычное связывание с RelativeSource={x:Static RelativeSource.Self} - person Thomas Levesque; 22.03.2012