tags:

views:

338

answers:

3

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 disenables me to use the underlying window..

+3  A: 

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.

HTH, Kent

Kent Boogaart
the brush is frozen so i cant change it :( is there any way around this?
Petoj
This worked like a charm but i have problems when trying to use it in a Style -> http://stackoverflow.com/questions/1443564/wpf-style-problem
Petoj
A: 

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.

Petoj
A: 

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.

Robert Macnee
what do you mean by lower level?
Petoj
Kent answered this in his second edit - you can add it as a resource of your main Window.
Robert Macnee