Search code examples
wpfbrightness

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


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.