Jak nadpisać nieprzezroczystość kontrolki nadrzędnej w WPF?

Gdy ustawisz krycie na Grid w WPF, wszystkie elementy potomne wydają się dziedziczyć Opacity. Jak można mieć element potomny, który nie odziedziczy nieprzezroczystości rodzica?

Na przykład poniższa siatka rodzica ma jedną siatkę potomną pośrodku z tłem ustawionym na czerwony, ale tło jest różowe ze względu na krycie rodzica. Chciałbym, aby dziecięca siatka miała jednolity kolor, nieprzezroczyste tło:

<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>
Author: Metro Smurf, 2010-04-16

3 answers

Udało mi się osiągnąć coś takiego w pure xaml za pomocą pędzla do malowania tła głównych siatek. W ten sposób tylko siatka nadrzędna będzie miała ustawioną krycie, a jej elementy potomne nie odziedziczą jej.

<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>
 40
Author: chiefanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-16 17:45:32

Możesz po prostu nałożyć dwie siatki wewnątrz siatki układu. Pierwsza byłaby zdefiniowana jako twoja siatka, minus twoja czerwona siatka wewnętrzna. Drugi byłby zdefiniowany z tymi samymi kolumnami i wierszami, z przezroczystym tłem. Jedynym dzieckiem tej siatki będzie twoja najbardziej wewnętrzna siatka.

    <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 -->
 3
Author: Wonko the Sane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-16 18:17:29

Jeśli chcesz, aby wszystkie dzieci kontenera nadrzędnego ustawiały własne krycie niezależnie od rodziców, możesz po prostu ustawić kanał alfa tła panelu nadrzędnego (zamiast ustawiania krycia), aby uzyskać lekko przezroczyste tło bez wpływu na elementy podrzędne. Coś takiego, gdzie 0C w tle jest kanałem alfa (AA w 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" />

Jeśli jednak chcesz, aby wszystkie dzieci z wyjątkiem jednego trzymały się nieprzezroczystości rodzica, to jest to trochę bardziej skomplikowane. Możesz to zrobić za pomocą ControlTemplate i kilku sprytnych sztuczek z kanałami Alfa lub maską krycia. Jeśli nie, możesz zbudować jakiś rodzaj niestandardowej kontroli, która dała ci zachowanie, które chciałeś. Musiałbym się nad tym trochę zastanowić, aby zobaczyć, co może być najlepszym rozwiązaniem dla tego typu scenariuszy.
 1
Author: Brad Cunningham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-16 05:11:30