tags:

views:

997

answers:

4

I am trying to get the effect of "dimming out the whole window and all controls on it".

The window and everything on it also needs to be disabled.

The problem is that when button is disabled, it doesn't seem to let you change the Background color.

Is there a way in WPF to change the background color of a button even though it is disabled?

XAML:

<Window x:Class="TestDimWindows.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

    <Grid x:Name="dimElement">
        <StackPanel HorizontalAlignment="Left">
            <TextBlock 
                Text="This is an example of dimming a window." 
                Margin="5"/>
            <StackPanel 
                HorizontalAlignment="Left" 
                Margin="5">
                <Button x:Name="theButton" 
                        Content="Dim the window" 
                        Click="Button_Click"/>
            </StackPanel>
        </StackPanel>
    </Grid>

</Window>

Code Behind:

using System.Windows;
using System.Windows.Media;

namespace TestDimWindows
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            dimElement.Background = new SolidColorBrush(Colors.Gray);
            dimElement.Opacity = 0.5;
            dimElement.IsEnabled = false;

            //I want this button to look "dimmed out" as well
            //but since it is disabled, it is a ghostly white.
            //how can I change the color even though it is disabled?
            theButton.Background = new SolidColorBrush(Colors.Gray);
        }
    }
}
+1  A: 

You can create your own control template for it.

I would suggest using Blend (you can get a trial edition if you don't have a license) to create a copy of the template you are currently using.

If you examine the current template, it must be setting the background color for disabled somewhere. Look for a trigger based on the IsEnabled property.

Josh G
A: 

You could just remove the onclick, and change the colour, and make that your 'disabled' state.

A: 

Look into the VisualBrush. You can set the visual of a VisualBrush to a control, and the VisualBrush will recreate a visual representation of a control, without any of the actual functionality.

I took this example from Sells/Griffiths' "Programming WPF" (Chapter 13 on Graphics) and modified it a little bit on my own, and then a bit more to demonstrate a solution for you.

What this does is create a simple drawing interface (inputting the x and y coordinates of 2 points to draw a line between), but also reflects the image below. Its not meant to be robust at all, but it should demonstrate the functionality I think you're looking for.
The last 2 rectangle elements with the VisualBrush and SolidColorBrush are how I create the duplicated control and then shade it out.

What you can do is overlay these 2 elements over the page/window/etc that you're looking to shade out, and then make them visible when you want the effect to take place.

Hope this helps.

<Window x:Class="GraphicsTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="1*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid x:Name="mainUI">
        <DockPanel>
            <GroupBox Header="Point 1" Name="gbPoint1" DockPanel.Dock="Top">
                <StackPanel Orientation="Horizontal">
                    <Label Width="40" HorizontalContentAlignment="Right">X:</Label>
                    <TextBox Name="tbX1" Width="40" TextChanged="Content_TextChanged"/>
                    <Label Width="40" HorizontalContentAlignment="Right">Y:</Label>
                    <TextBox Name="tbY1" Width="40" TextChanged="Content_TextChanged"/>
                </StackPanel>
            </GroupBox>
            <GroupBox Header="Point 2" Name="gbPoint2"  DockPanel.Dock="Top">
                <StackPanel Orientation="Horizontal">
                    <Label Width="40" HorizontalContentAlignment="Right">X:</Label>
                    <TextBox Name="tbX2" Width="40" TextChanged="Content_TextChanged"/>
                    <Label Width="40" HorizontalContentAlignment="Right">Y:</Label>
                    <TextBox Name="tbY2" Width="40" TextChanged="Content_TextChanged"/>
                </StackPanel>
            </GroupBox>
            <Canvas>
                <Line Name="lnDraw" Stroke="Black" StrokeThickness="2"/>
            </Canvas>
        </DockPanel>
    </Grid>
    <Rectangle Grid.Row="1">
        <Rectangle.LayoutTransform>
            <ScaleTransform ScaleY="-1"/>
        </Rectangle.LayoutTransform>
        <Rectangle.Fill>
            <VisualBrush Visual="{Binding ElementName=mainUI}" />
        </Rectangle.Fill>
    </Rectangle>
    <Rectangle Grid.Row="1">
        <Rectangle.Fill>
            <SolidColorBrush Color="Black" Opacity=".5"/>
        </Rectangle.Fill>
    </Rectangle>
</Grid>

And the .cs

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
    }

    private void Content_TextChanged(object sender, TextChangedEventArgs e)
    {
        int x1;
        int x2;
        int y1;
        int y2;

        if (int.TryParse(tbX1.Text, out x1) && int.TryParse(tbX2.Text, out x2) && int.TryParse(tbY1.Text, out y1) && int.TryParse(tbY2.Text, out y2))
        {
            lnDraw.X1 = x1;
            lnDraw.X2 = x2;
            lnDraw.Y1 = y1;
            lnDraw.Y2 = y2;
        }
    }
}
Drew McGhie
A: 

I would attempt a dim out effect with a rectangle that fills the whole grid, is gray, has an opacity smaller than 1 and a z-index higher than your normal controls. By default the rectangle would have visibility = collapsed, then I would use a trigger to set its visibility to visible when some appropriate "IsEnabled" property goes to "true".

flq