Нуждаете се от съвет как да смените цветовете

Създавам 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, ако сте направили свойството обкръжаващо с флага Inherits, можете да използвате нормално обвързване с RelativeSource={x:Static RelativeSource.Self} - person Thomas Levesque; 22.03.2012