Question

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

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top