Peter
Peter

Reputation: 38545

WPF change brightness

Well i have a application that is black and white and i need a function to lower the brightness how can i do this? all the white comes from a SolidColorBrush that is saved in a ResourceDictionary(Application.xaml), my current solution is to put a empty window that is back with 80% opacity over it but this does not allow me to use the underlying window..

Upvotes: 4

Views: 6450

Answers (3)

Kent Boogaart
Kent Boogaart

Reputation: 178780

If all your UI elements are using the same Brush, why not just modify the Brush to reduce the brightness? For example:

public void ReduceBrightness()
{
    var brush = Application.Resources("Brush") as SolidColorBrush;
    var color = brush.Color;
    color.R -= 10;
    color.G -= 10;
    color.B -= 10;
    brush.Color = color;
}

Edit after your comment on the Brush being frozen:

If you're using one of the built-in brushes (via the Brushes class) then it will be frozen. Instead of using one of them, declare your own Brush without freezing it:

<SolidColorBrush x:Key="Brush">White</SolidColorBrush>

Edit after Robert's comment on Application-level resources:

Robert is right. Resources added at the Application level are automatically frozen if they are freezable. Even if you explicitly ask for them not to be frozen:

<SolidColorBrush x:Key="ForegroundBrush" PresentationOptions:Freeze="False" Color="#000000"/>

There are two ways around this that I can see:

  1. As Robert suggested, put the resource at a lower level in the resource tree. For example, in a Window's Resources collection. This makes it harder to share though.
  2. Put the resource in a wrapper that is not freezable.

As an example of #2 consider the following.

App.xaml:

<Application.Resources>
    <FrameworkElement x:Key="ForegroundBrushContainer">
        <FrameworkElement.Tag>
            <SolidColorBrush PresentationOptions:Freeze="False" Color="#000000"/>
        </FrameworkElement.Tag>
    </FrameworkElement>
</Application.Resources>

Window1.xaml:

<StackPanel>
    <Label Foreground="{Binding Tag, Source={StaticResource ForegroundBrushContainer}}">Here is some text in the foreground color.</Label>
    <Button x:Name="_button">Dim</Button>
</StackPanel>

Window1.xaml.cs:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        _button.Click += _button_Click;
    }

    private void _button_Click(object sender, RoutedEventArgs e)
    {
        var brush = (FindResource("ForegroundBrushContainer") as FrameworkElement).Tag as SolidColorBrush;
        var color = brush.Color;
        color.R -= 10;
        color.G -= 10;
        color.B -= 10;
        brush.Color = color;
    }
}

It's not as pretty, but it's the best I can come up with right now.

Upvotes: 5

Robert Macnee
Robert Macnee

Reputation: 11840

Kent's solution will work if the SolidColorBrush is added to the resources at a lower level. Freezables are automatically frozen when they're added to Application.Resources.

Upvotes: 0

Peter
Peter

Reputation: 38545

Solved this by changing the Opacity of my root element instead of trying to modify a brush but it would still be nice if some told me if i can do that some how or its not possible.

Upvotes: 0

Related Questions