#810 – Setting Foreground and Background Properties from Code

You can set both the Foreground and Background properties at run-time, from code.  Recall that both properties are set to an instance of a Brush, which can be a SolidColorBrush,  one of the GradientBrush subtypes, or one of several other different types of Brush objects.

The simplest way to change a Foreground or Background property, assuming that you want to set them to a solid color, is to set the property to refer to one of the preexisting SolidColorBrush objects that are part of the Brushes class.

The Brushes class includes a set of static SolidColorBrush objects, each representing one of the standard predefined colors.

        <Label Name="lblMA" Content="Margaret Atwood" HorizontalAlignment="Center"
               Padding="20,10" Margin="10"
               Background="LightPink"/>
        <Button Content="Change Color" HorizontalAlignment="Center"
                Padding="10,5" Click="Button_Click"/>

810-001

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // Set to one of the predefined brushes
            lblMA.Background = Brushes.Plum;
        }

810-002

Advertisement

#557 – Using an Image As an Opacity Mask

You’ll typically use a gradient brush as an opacity mask, to change the opacity of a control gradually.

You can also use an image as an opacity brush, making various regions of the target control opaque or transparent depending on the opacity at the same spot in the image.

Below, I’ve created a smiley face image in Paint.NET.  I’ve made the background of the image transparent (shown in Paint.NET as a checkerboard).

Next I create a WPF project with a simple Image control.

    <Image Source="Images\Rocks2Small.jpg" Width="400"/>

Now we specify an OpacityMask for this Image.  But instead of using a LinearGradientBrush or RadialGradientBrush, we use an ImageBrush–a brush created from an image.

<Image Source="Images\Rocks2Small.jpg" Width="400">
    <Image.OpacityMask>
        <ImageBrush ImageSource="Images\FaceMask.png"/>
    </Image.OpacityMask>
</Image>

Using the second image as the opacity mask for the first means–the first image will be transparent wherever the second image is transparent.

#556 – Clipping to a Border Using an Opacity Mask

When you specify a border radius for a Border element, the content within the Border is not automatically clipped to the new rounded interior.

<Border BorderBrush="Black" BorderThickness="3" Margin="10"
        Width="400" Height="267" CornerRadius="40" >
    <Image Source="Images\Rocks2Small.jpg"/>
</Border>


If you want to clip against the Border, you can specify an opacity mask that is a visual brush bound to the visual of a second Border element that overlays the Image control.  This will cause any portion of the Image control that falls outside the boundaries of the inner Border to use an opacity of 0.0.

<Border BorderBrush="Black" BorderThickness="3" Margin="10" Width="400" Height="267"
	CornerRadius="40" >
    <Grid>
        <Border	Name="myBorder" CornerRadius="40" Background="White" Margin="1"/>
	<Image Source="Images\Rocks2Small.jpg" Margin="1">
	    <Image.OpacityMask>
	        <VisualBrush Visual="{Binding ElementName=myBorder}"/>
	    </Image.OpacityMask>
	</Image>
    </Grid>
</Border>


Thanks to fellow Minnesotan, Chris Cavanagh, for an explanation of how to do this!

#209 – Specifying a Color Where a Brush Is Expected in XAML

We saw earlier how to set the Background property for a control in XAML, by setting the property to an instance of a SolidColorBrush and then setting the Color property for the brush:

    <Window.Background>
        <SolidColorBrush Color="PowderBlue"/>
    </Window.Background>

We can be much more concise than this, however, just setting the value of the Background property directly to a color:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="346" Width="590"
        Background="PowderBlue">

This works through the use of type converters.  The Background property uses a type converter to convert a string to an instance of a SolidColorBrush of the corresponding color.  Specifically, it sets the property to point to the preexisting Brushes.PowderBlue brush.  You can see the full list of predefined brushes here.

#174 – Predefined Brushes Are Already Frozen

All of the brushes in the predefined Brushes collection are already in a frozen state, meaning that they are read-only.  Being frozen means that they will perform more efficiently when using them to render graphical objects, since WPF doesn’t need to worry about notifying consumers of the brush when the brush changes.

Here’s an example, where we have two different labels, one painted with a brush created in XAML and one painted with a brush from the Brushes collection.

    <Window.Resources>
        <SolidColorBrush x:Key="tealBrush" Color="Teal"/>
    </Window.Resources>
    <StackPanel>
        <Label Name="lblWithTealBrush" Content="I use a SolidColorBrush created in Window.Resources" Foreground="{StaticResource tealBrush}"/>
        <Label Name="lblWithRedBrush" Content="I use Brushes.Red">
            <Label.Foreground>
                <x:Static Member="Brushes.Red"/>
            </Label.Foreground>
        </Label>
        <Button Content="Click Me" Width="100" Click="btnTest_Click"/>
    </StackPanel>

We can add code to check the frozen state of these two different brushes.

        private void btnTest_Click(object sender, RoutedEventArgs e)
        {
            SolidColorBrush tealBrush = (SolidColorBrush)lblWithTealBrush.Foreground;
            bool frozen = tealBrush.IsFrozen;    // frozen = false

            SolidColorBrush redBrush = (SolidColorBrush)lblWithRedBrush.Foreground;
            frozen = redBrush.IsFrozen;          // frozen = true
        }