2

How do I change the foreground property of multiple controls in a XAML window, when not all the controls are the same type?

I can set TextElement.Foreground in a stackpanel, to set the foreground color of TextBoxes, etc (see code below). However, this will not change the foreground color of Buttons, ListBoxes, etc.

How can I set the foreground color for all elements in a window, without setting it for each individual element or class of elements?

<Window x:Class="XAMLViewTests.AnimationsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="AnimationsWindow" Height="300" Width="300">
    <StackPanel TextElement.Foreground="Blue">
        <ToolBarTray>
            <ToolBar>
                <TextBlock>Test Tray 1</TextBlock>
            </ToolBar>
            <ToolBar>
                <TextBlock>Test Tray 2</TextBlock>
            </ToolBar>
            <ToolBar>
                <Button>Test Tray 3</Button>
            </ToolBar>
        </ToolBarTray>
        <TextBlock>Test TextBlock</TextBlock>
        <Button>Test Button</Button>
        <ListBox>ListBox 1
            <ListBoxItem>Item 1</ListBoxItem>
            <ListBoxItem>Item 2</ListBoxItem>
        </ListBox>
    </StackPanel>
</Window>
Aaron Thomas
  • 5,054
  • 8
  • 43
  • 89

3 Answers3

4

Further to James' answer: you could use WPF's ability to inherit styles, and the fact that Foreground is a property of the base Control class, in order to reduce duplication of the setter:

<Style TargetType="Control">
  <Setter Property="Foreground" Value="Red" />
</Style>

<Style BasedOn="{StaticResource {x:Type Control}}" TargetType="Button">
  <!-- optionally add button-specific stuff here... -->
</Style>

<Style BasedOn="{StaticResource {x:Type Control}}" TargetType="TextBox">
<!-- optionally add textbox-specific stuff here... -->
</Style>

<Style BasedOn="{StaticResource {x:Type Control}}" TargetType="ComboBox">
  <!-- optionally add ComboBox-specific stuff here... -->
</Style>
Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
3

I think you'd need to style the controls you want to be affected individually - but just once for each - assuming you want all instances of TextBlock / TextBox / Button etc. to be affected.

<Window.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="Foreground" Value="White"/>
    </Style>
    <Style TargetType="TextBox">
        <Setter Property="Foreground" Value="White"/>
    </Style>
    <Style TargetType="Button">
        <Setter Property="Foreground" Value="White"/>
    </Style>
<Window.Resources>
James Harcourt
  • 6,017
  • 4
  • 22
  • 42
0

The previous two answers are correct. After more researching, I also wanted to mention this could be accomplished with tree traversal.

Some references I found: This SO question and answers, and the MSDN article "Trees in WPF."

Community
  • 1
  • 1
Aaron Thomas
  • 5,054
  • 8
  • 43
  • 89
  • 1
    Doing this in-code through tree-traversal is pretty clunky, though, and defeats the point of XAML as your presentation layer, as you'd have to define your style in-code. – Dan Puzey Jun 08 '15 at 16:26
  • @DanPuzey I agree on all counts! Just wanted to mention it was an option, even if not the best for the context of this question. – Aaron Thomas Jun 08 '15 at 16:43