views:

479

answers:

3

When you set the opacity on a Grid in WPF, all the child elements appear to inherit its Opacity. How can you have a child element not inherit the parent's opacity?

For example, the following parent grid has one child grid in the middle with a background set to red, but the background appears pinkish because of the parent's opacity. I'd like the child grid to have a solid color, non-transparent background:

<Grid x:Name="LayoutRoot">

  <Grid Background="Black" Opacity="0.5">
    <Grid.RowDefinitions>
      <RowDefinition Height="0.333*"/>
      <RowDefinition Height="0.333*"/>
      <RowDefinition Height="0.333*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="0.333*"/>
      <ColumnDefinition Width="0.333*"/>
      <ColumnDefinition Width="0.333*"/>
    </Grid.ColumnDefinitions>

    <-- how do you make this child grid's background solid red
        and not inherit the Opacity/Transparency of the parent grid? -->
    <Grid Grid.Column="1" Grid.Row="1" Background="Red"/>
  </Grid>

</Grid>
A: 

If you want all the children of the parent container to set their own opacity regardless of the parents you can just set the alpha channel of the parent panel's background (instead of setting opacity) to get a slightly transparent background without impacting the child elements. Something like this, where the 0C in the background is the Alpha channel (the AA in AARRGGBB):

<Grid Grid.Column="0"
      Grid.Row="1"
      Background="Red"
      Opacity="1" />

<Grid Grid.Column="1"
      Grid.Row="1"
      Background="Green" />

<Grid Grid.Column="2"
      Grid.Row="1"
      Background="Blue" />

However, if you want all the children except one to adhere to the parent's opacity that is a little more complicated. You might be able to do that with a ControlTemplate and some clever tricks with the Alpha channels or an opacity mask. If not you could build some sort of custom control that gave you the behavior you wanted. I would have to think about it for a bit to see what might be the best solution for that type of scenario.

Foovanadil
The intent is to have all children except one to adhere to the parent's opacity. Maybe there's something that could be set in native xaml without building a custom control?
Metro Smurf
+1  A: 

I was able to achieve something like this in pure xaml using a Brush to paint the main grids background. This way only parent grid will have its opacity set and its child elements won't inherit it.

<Grid x:Name="LayoutRoot">       
      <Grid>
        <Grid.Background>
            <SolidColorBrush Color="Black" Opacity="0.5"/>
        </Grid.Background>
        <Grid.RowDefinitions>
          <RowDefinition Height="0.333*"/>
          <RowDefinition Height="0.333*"/>
          <RowDefinition Height="0.333*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="0.333*"/>
          <ColumnDefinition Width="0.333*"/>
          <ColumnDefinition Width="0.333*"/>
        </Grid.ColumnDefinitions>

        <Grid Grid.Column="1" Grid.Row="1" Background="Red" />
      </Grid>   
</Grid>
chiefanov
thanks chief. The solid color brush did the trick! And welcome to StackOverflow \(*_*)/
Metro Smurf
+1  A: 

You can just overlay two grids inside your layout grid. The first would be defined as your grid, minus your red innermost grid. The second would be defined with the same columns and rows, with a transparent background. The only child of this grid would be your innermost grid.

    <Grid x:Name="LayoutRootNew" 
          HorizontalAlignment="Stretch" 
          VerticalAlignment="Stretch">

        <Grid Background="Black" Opacity="0.5">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.333*"/>
                <RowDefinition Height="0.333*"/>
                <RowDefinition Height="0.333*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.333*"/>
                <ColumnDefinition Width="0.333*"/>
                <ColumnDefinition Width="0.333*"/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0" Grid.Row="0">
                 Here is some content in a somewhat transparent cell  
            </TextBlock>

        </Grid> <!-- End of First Grid -->

        <!-- Second grid -->
        <Grid Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="0.333*"/>
                <RowDefinition Height="0.333*"/>
                <RowDefinition Height="0.333*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.333*"/>
                <ColumnDefinition Width="0.333*"/>
                <ColumnDefinition Width="0.333*"/>
            </Grid.ColumnDefinitions>

            <Grid Grid.Column="1" Grid.Row="1" Background="Red">
                <TextBlock Foreground="White" Text="Here Is Your Red Child" />
            </Grid> <!-- Inner Child Grid -->
        </Grid> <!-- End of Second Grid -->
    </Grid>     <!-- Layout Grid -->
Wonko the Sane
@Wonko, thank you. This method is a good alternative to what chief's answer provided.
Metro Smurf