WPF multiple control property simultaneous changes

763 views Asked by At

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>
3

There are 3 answers

0
James Harcourt On BEST ANSWER

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>
0
Dan Puzey On

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>
2
Aaron Thomas On

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."