image

Translucent Background Color

 

While working on a WinRT project (Windows 8 Store App), I came across an interesting problem; how do I bind the Background property of a Border element to a SolidColorBrush but then set the opacity of that same brush to get the translucent look behind the text?

The answer came in a few steps. The first step was discovering how to create a background brush within the XAML data:

    <DataTemplate x:Key="Standard360x120NewsTemplate">
        <Grid Height="120" Width="360" Margin="0" Background="Transparent">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" HorizontalAlignment="Left" Height="120" Width="120" Background="{Binding Background}">
                <Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding Image}" Stretch="None" AutomationProperties.Name="{Binding Title}"/>
            </Border>
            <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="0,0,0,0">
                <StackPanel.Background>
                    <SolidColorBrush Color="#ff555555" Opacity="0.30" />
                </StackPanel.Background>
                <TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" Height="22" Margin="15,0,15,0"/>
                <TextBlock Text="{Binding Subtitle}" Style="{StaticResource BodyTextStyle}" Height="98" TextWrapping="Wrap" Margin="15,0,15,6"/>
            </StackPanel>
        </Grid>
    </DataTemplate>

The code listing above shows the data template for the news item. I am still learning the fine details of XAML and data binding so some of what I show may be incomplete or non-standard. Anyhow, the StackPanel that contains the text is in the second column of the grid one line 10. The Background property is set by creating the SolidColorBrush right here in this XAML within the <StackPanel.Background> tag. By doing this, the color and opacity can be set separately.

This listing is not quite correct; what you see in the listing above is just a gray background color and not the blue tile color. The next step that did not work was to set the color to the same Binding Background value that is used for the square (see line 7 above where the square gets its background):

<SolidColorBrush Color="{Binding Background}" Opacity="0.30"/>

This obviously won’t work. It is not obvious here but “Background” is a property of the data item class and it is a SolidColorBrush, not a Color. This is probably obvious to others but I had to discover this myself. So I changed the code like this:

<SolidColorBrush Color="{Binding BackgroundColor}" Opacity="0.30"/>

And now one final step; create a BackgroundColor variable in the news item class so that the binding will work. To make a long story short, I create a BackgroundColor property and set it to the color of the brush that is used for the background:

    public abstract class BaseDataItem : w8test2.Common.BindableBase
    {
        public BaseDataItem(String uniqueId, String title, String subtitle, String imagePath, String description, SolidColorBrush background )
        {
            this._uniqueId = uniqueId;
            this._title = title;
            this._subtitle = subtitle;
            this._description = description;
            this._imagePath = imagePath;
            this._background = background;
            this._backgroundcolor = background.Color;
        }

        private string _uniqueId = string.Empty;
        public string UniqueId
        {
            get { return this._uniqueId; }
            set { this.SetProperty(ref this._uniqueId, value); }
        }

        private string _title = string.Empty;
        public string Title
        {
            get { return this._title; }
            set { this.SetProperty(ref this._title, value); }
        }

        private string _subtitle = string.Empty;
        public string Subtitle
        {
            get { return this._subtitle; }
            set { this.SetProperty(ref this._subtitle, value); }
        }

        private SolidColorBrush _background = new SolidColorBrush( Windows.UI.Color.FromArgb( 0xff,0xff, 0x00, 0x00 ) );
        public SolidColorBrush Background
        {
            get { return this._background; }
            set
            {
                this.SetProperty(ref this._background, value); 
                this.SetProperty(ref this._backgroundcolor, value.Color); 
            }
        }

        private Color _backgroundcolor = new Color();
        public Color BackgroundColor
        {
            get { return this._backgroundcolor; }
            set 
            {
                this.SetProperty(ref this._background, new SolidColorBrush( value )); 
                this.SetProperty(ref this._backgroundcolor, value); 
            }
        }

        private string _description = string.Empty;
        public string Description
        {
            get { return this._description; }
            set { this.SetProperty(ref this._description, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;
        public ImageSource Image
        {
            get
            {
                if (this._image == null && this._imagePath != null)
                {
                    this._image = new BitmapImage(new Uri(BaseDataItem._baseUri, this._imagePath));
                }
                return this._image;
            }

            set
            {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }
    }

This may look familiar for those who use the built-in pages when creating a Windows Store app in Visual Studio.

Line 11 is where the important step happens. The BackgroundColor property is set to the supplied brush color. Down at lines 42 and 52, the BackgroundColor property is handled in a similar fashion where setting the brush again sets the color but setting the color will also create a brush. This code doesn’t get used in my program because I don’t bind in both directions. Only the constructor code gets called (as far as I know).

This is a tiny bit ugly because the XAML relies on there being the very specific BackgroundColor property but this seems acceptable since it is handled by my data item base class and the XAML relies on other specific properties of that same base class.

And with the BackgroundColor property being used, this is how the tile, now in Green, looks:

image

Translucent Background Color Matching Background Brush

I opted to use a gray color in the end because shading to match the solid square color didn’t look as good to me. But given the right circumstance, this method could prove to be very useful and the green version is not really that bad.

 

Dave