使用模糊效果使标签/文本块在玻璃上可读

时间:2011-02-11 18:05:48

标签: c# .net wpf presentation

我正在使用WPF 3.5 SP1,我希望实现类似的功能(玻璃部件已经完成):

http://lh3.ggpht.com/_0B12UOQNmgU/SwPqI4FcYaI/AAAAAAAAASM/HKFPyZ9uX3o/Aero%20Glass.jpg
Source


Source

你可以在文本周围看到漂亮的模糊,这使它非常易读。我还发现正确的方法是使用API​​ DrawThemeTextEx,它使用推荐的系统选项渲染模糊。但是,如何使用WPF实现相同的效果?

我能够找到包含有用资源的链接:
How to make WPF text on Aero glass background readable?
Glowing Label Controls On A Glass Surface

他们通过复制TextBlock并在其上设置模糊效果来实现。但是,这不是一个真正的解决方案。这是它的样子:

http://i53.tinypic.com/2ly67nq.png

将结果效果与上面的图像进行比较,您将看到解决方案仍然很遥远。那么如何使用WPF正确获得所需的效果呢?我对仿真很好(不使用DrawThemeTextEx API),只要结果非常相似。

谢谢。

4 个答案:

答案 0 :(得分:7)

    <TextBlock ...>
        <TextBlock.Effect>
            <DropShadowEffect BlurRadius="10" Color="White" ShadowDepth="0" />
        </TextBlock.Effect>
    </TextBlock>

答案 1 :(得分:7)

根据Luke的要求,我为XAML s添加了Decorator

<Decorator>
    <Decorator.Effect>
        <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
    </Decorator.Effect>
    <Decorator>
        <Decorator.Effect>
            <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
        </Decorator.Effect>
        <Decorator>
            <Decorator.Effect>
                <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
            </Decorator.Effect>

            <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
                    Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" 
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
        </Decorator>
    </Decorator>
</Decorator>

我使用前面提到的XAML为ControlTemplate创建了一个Label,并在我需要文本发光的任何地方使用它。

答案 2 :(得分:2)

在这些行中你的文字后面有一个矩形略微模糊的东西怎么样,我已经使用了几次。我发现它使它更具可读性,因为模糊覆盖了更大的区域。

            <Grid>
                <Rectangle Fill="#8FFFFFFF"
                           Stroke="{x:Null}"
                           StrokeThickness="0"
                           VerticalAlignment="Center"
                           Width="{Binding ActualWidth, ElementName=PART_Title, Mode=Default}"
                           Height="{Binding ActualHeight, ElementName=PART_Title, Mode=Default}"
                           RadiusX="2"
                           RadiusY="2">
                    <Rectangle.Effect>
                        <BlurEffect Radius="10" />
                    </Rectangle.Effect>
                </Rectangle>

                <TextBlock x:Name="PART_Title"
                           Text="{Binding Title}"
                           Foreground="Black"
                           TextWrapping="NoWrap"
                           TextTrimming="CharacterEllipsis" />
            </Grid>

答案 3 :(得分:1)

我在Paya的答案中实现装饰器时遇到了麻烦,所以我展示了如何将它包装成一个完整的,随时可用的样式资源,可以应用于任何标签,这将显示玻璃效果,并且在禁用时也会使标签变暗并保留对齐,边框等:

<Style x:Key="GlassLabelStyle" TargetType="{x:Type Label}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Label}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" 
                BorderThickness="{TemplateBinding BorderThickness}" 
                Background="{TemplateBinding Background}" 
                Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                    <Grid>
                        <Decorator>
                            <Decorator.Effect>
                                <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
                            </Decorator.Effect>
                            <Decorator>
                                <Decorator.Effect>
                                    <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
                                </Decorator.Effect>
                                <Decorator>
                                    <Decorator.Effect>
                                        <DropShadowEffect BlurRadius="7" Color="White" ShadowDepth="0" />
                                    </Decorator.Effect>
                                    <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" 
                    Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" 
                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                    </ContentPresenter>
                                </Decorator>
                            </Decorator>
                        </Decorator>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        <Setter Property="Opacity" Value="0.5"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如果样式位于您的窗口或应用资源中,那么您可以像这样应用它:

<Label Style="{StaticResource GlassLabelStyle}"

虽然我在使用它时,我也遇到了TextBox的问题,当控件被禁用时它根本无法改变背景颜色(它只是保持恢复为白色)所以有人发现你必须覆盖整个模板!见(https://stackoverflow.com/a/3752517/88409)。因此,这是一个随时可用的样式,可以在禁用时使文本框保持半透明(在玻璃上看起来很棒),并且在启用时将使其背景为半透明白色,边框更明显:

<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#01000000" />
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#40000000" />
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#88ffffff" />

<Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Background" Value="#88ffffff"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
                                    BorderBrush="{TemplateBinding BorderBrush}" 
                                    Background="{TemplateBinding Background}" 
                                    SnapsToDevicePixels="true">
                    <ScrollViewer Name="PART_ContentHost" Background="{TemplateBinding Background}" 
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Value="{StaticResource DisabledBackgroundBrush}" Property="Background" />
                        <Setter Value="{StaticResource DisabledBorderBrush}" Property="BorderBrush"/>
                        <Setter Value="{StaticResource DisabledForegroundBrush}" Property="Foreground" />
                        <Setter TargetName="PART_ContentHost" Property="Background" Value="{StaticResource DisabledBackgroundBrush}"/>
                        <Setter TargetName="PART_ContentHost" Property="BorderBrush" Value="{StaticResource DisabledBackgroundBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>