ControlTemplate Opacity not displayed like I want

2019-09-15 05:50发布

问题:

I have a Style defined for my DataGridCell

<Style x:Key="MYDGCellStyle" TargetType="{x:Type DataGridCell}">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Template" Value="{DynamicResource MYDGCellControlTemplate}" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsReadOnly}" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <SolidColorBrush Color="Gray" Opacity="0.3" />
                    </Setter.Value>
                </Setter>
            </DataTrigger>                
        </Style.Triggers>
    </Style>

    <ControlTemplate x:Key="MYDGCellControlTemplate" TargetType="{x:Type DataGridCell}">
        <Grid x:Name="CellGrid">
            <Border Background="{TemplateBinding Background}">
                <ContentPresenter VerticalAlignment="Center" Margin="4,0,6,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
            </Border>                
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsFocused" Value="true">
                <Setter Property="Background" TargetName="CellGrid">
                    <Setter.Value>
                        <LinearGradientBrush Opacity="2" StartPoint="0,0.5" EndPoint="1,0.5">
                            <GradientStop Offset="0" Color="Fuchsia" />
                            <GradientStop Offset="0.2" Color="Transparent" />
                            <GradientStop Offset="0.8" Color="Transparent" />
                            <GradientStop Offset="1" Color="Fuchsia" />
                        </LinearGradientBrush>                            
                    </Setter.Value>
                </Setter>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

During Runtime I add additional Triggers for specific Columns like this in my Code

Style Sty = null;
if (Sty == null)
{
    Sty = new Style(typeof(DataGridCell));                                
    Sty.BasedOn = (Style)Application.Current.TryFindResource("MYDGCellStyle");                                
}

DataTrigger t = new DataTrigger();
t.Binding = new Binding("ProductionStatus");
t.Value = "I";
Setter s = new Setter();
s.Property = DataGridCell.BackgroundProperty;
s.Value = new SolidColorBrush(Colors.Gold) { Opacity = 0.5 };
t.Setters.Add(s);

Sty.Triggers.Add(t);
DGC.CellStyle = Sty;

But if I focus one of the Cells where a DataTrigger I added in my Code is triggerd the Color isn't displayed correctly.

How can I display the fuchsia Sides in front of the Gold Background?

Grey Cell Focused:

Gold Cell Focused:

UPDATE

<ControlTemplate x:Key="MYDGCellControlTemplate" TargetType="{x:Type DataGridCell}">            
            <Grid>
            <Grid Grid.ZIndex="99"  x:Name="CellGrid"/>
            <Border Grid.ZIndex="98" Background="{TemplateBinding Background}">
                    <ContentPresenter VerticalAlignment="Center" Margin="4,0,6,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </Border>
            </Grid>            
        <ControlTemplate.Triggers>
            <Trigger Property="IsFocused" Value="true">
                <Setter Property="Background" TargetName="CellGrid">
                    <Setter.Value>
                        <LinearGradientBrush Opacity="2" StartPoint="0,0.5" EndPoint="1,0.5">
                            <GradientStop Offset="0" Color="Fuchsia" />
                            <GradientStop Offset="0.1" Color="#00FF00FF" />
                            <GradientStop Offset="0.9" Color="#00FF00FF" />
                            <GradientStop Offset="1" Color="Fuchsia" />
                        </LinearGradientBrush>                            
                    </Setter.Value>
                </Setter>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

回答1:

Your problem might be, that you apply a golden color brush above the fuchsia edges, so they get tinted by 50% of gold.

s.Value = new SolidColorBrush(Colors.Gold) { Opacity = 0.5 };

Additionally you should be aware that using Transparent in XAML means "white with no opacity", so if you want to fade out funchsia you should not fade to transparent white, but to transparent fuchsia instead.

White:               #FFFFFFFF
Transparent:         #00FFFFFF
Fuchsia opaque:      #FFFF00FF
Fuchsia transparent: #00FF00FF

To enforce the z-order you could use an additional container around the item given and apply the status here "during runtime". Anyway this will not be an MVVM approach.

The better way might be to define a custom template-parameter (bool IsSpecificColumn) in your XAML, which will be set in your code "during runtime". Using MultiTrigger you can also define a third state for gold+fuchsia.

If you have to combine even more states you should let WPF do the job and use the approach with the boxed containers mentioned above together with template-parameters.



回答2:

Try creating a new "IsFocused" trigger in your new style(I ProductionStatus)like this:

<Trigger Property="IsFocused" Value="true">
    <Setter Property="Background" TargetName="CellGrid">
        <Setter.Value>
            <LinearGradientBrush Opacity="2" StartPoint="0,0.5" EndPoint="1,0.5">
                <GradientStop Offset="0" Color="Fuchsia" />
                <GradientStop Offset="0.2" Color="Gold" />
                <GradientStop Offset="0.8" Color="Gold" />
                <GradientStop Offset="1" Color="Fuchsia" />
             </LinearGradientBrush>                            
         </Setter.Value>
    </Setter>
</Trigger>

I know you are doing it on code behind, but I think you'll understand me(easyer to copy-paste).