Замяна на стандартната тема в App.xaml

Използвам стандартната WPF тема Aero.NormalColor.xaml. И работи много добре. За цялото приложение обаче бих искал да заменя цвета на предния план на текстовите полета с червен.

Първият ми опит е това

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="TextBox">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

Е... всички цветове на предния план на текстовите полета стават червени. Всички текстови полета обаче губят стила на темата. Да, знам, че трябва да добавя "BasedOn". Вторият ми опит е да добавя "BasedOn" в етикета за стил.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

Прави се изключение. Същото като този WPF: Разширете стила на темата - StackOverflowException

В крайна сметка постигам целта си с това.

В App.xaml

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary
                Source="/PresentationFramework.Aero, Version=3.0.0.0,
               Culture=neutral, PublicKeyToken=31bf3856ad364e35,
               ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

И във всички прозорци и потребителски контрол трябваше изрично да задам

<UserControl.Resources>
    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</UserControl.Resources>

Горният код се копира и поставя много пъти и не е лесен за поддръжка. Някой знае ли как да постигна целта си, като просто задам предния план на червено веднъж?


person Alex Yeung    schedule 23.11.2009    source източник


Отговори (3)


Мисля, че можете да добавите Style към ResourceDictionary и да го обедините с темата Aero по следния начин:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35,
        ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml">
      </ResourceDictionary>

      <!-- Adding the style to a resource dictionary -->
      <ResourceDictionary>
        <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
          <Setter Property="Foreground" Value="Red" />
        </Style>
      </ResourceDictionary>

    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

Това трябва да даде на ВСИЧКИ ваши текстови полета червен цвят на преден план, без да се налага изрично да го указвате на всеки прозорец и потребителски контрол.

person Oskar    schedule 24.11.2009
comment
За мен свърши работа - но по-добре трябва да поставите стила на текстовото поле в отделен файл с речник на ресурси (напр. TextBoxStyles.xaml) и просто да добавите ‹ResourceDictionary Source=TextBoxStyles.xmal /› към обединения речник. В противен случай може да се сблъскате с грешка с обединени речници, което води до ситуация, при която стилът не се прилага към първото създадено текстово поле... - person Schweder; 15.03.2012

Имах същия проблем и опитах подхода на Оскар. Въпреки това, това предизвика някакво странно поведение. По-специално, стиловете не се прилагат за някои контроли, докато се прилагат за други контроли от същия тип. И не можах да намеря големи разлики между тези контроли.

Продължих да търся решението и го намерих тук: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/91718816-8674-4ad8-a3c8-ae283bebe224/

Все още не е перфектно и ясно, но работи, поне при мен.

Накратко, можете да получите идеята от следния код:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0,
        Culture=neutral, PublicKeyToken=31bf3856ad364e35,
        ProcessorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml" />
                </ResourceDictionary.MergedDictionaries>
                <Style x:Key="ExtendedTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
                    <Setter Property="Foreground" Value="Red" />
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource ExtendedTextBoxStyle}" />
    </ResourceDictionary>
</Application.Resources>

За поддръжка и четливост тези вложени ResourceDictionary обекти могат да отидат в отделни XAML файлове.

person Alex Che    schedule 08.02.2010

Точният отговор на този въпрос е задаване на целия персонализиран стил въз основа на стойност от статичен ресурс на текущия контрол. Някои контроли обаче може да нямат стил по подразбиране като ListView или ListViewItem.

<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Width" Value="250" />
    <Setter Property="Height" Value="25" />
</Style>

Този стил може да се намери във всякакъв вид речник на ресурси като ресурси на прозорци, ресурси на мрежа, ресурси на текстово поле или речник на външни ресурси.

И накрая, трябва да добавите тема на речника на ресурса към ресурсите на вашето приложение, като следния код, който добавя тема Aero към моето приложение.

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/PresentationFramework.Aero, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
            <ResourceDictionary Source="/Themes/Default.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>
person Soul_Master    schedule 15.08.2011