読者です 読者をやめる 読者になる 読者になる

SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

Labelの上下と背景をグラデーションで装飾する

↓の記事で紹介されていた、テキストの上下と背景をグラデーションで装飾するというデザインを、WPFで真似してみました。
[CSS]テキストの天地に美しいグラデーションのボーダーと背景を適用するスタイルシート | コリス


結果はこんな感じ。
f:id:minami_SC:20140114015640p:plain


ちなみに、TextBlockはFrameworkElementから派生していてTemplateプロパティを持っておらず、
ControlTemplateのカスタマイズができないので、ここではLabelコントロールに対するStyleを定義しています。

とりあえずコード

以下のようなStyleを定義しました。
TemplateBindingを使って、LabelのBackgroundプロパティの色をテキスト上下のボーダーと背景色に使用しています。
あと、LabelのPaddingプロパティをContentPresenterのMarginにバインドしています。
こうすることで、LabelのPaddingプロパティで、文字とボーダーまでの距離を調整できるようにしてます。

        <Style x:Key="GradientBorderLabelStyle" TargetType="{x:Type Label}">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Padding" Value="5" />
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="VerticalContentAlignment" Value="Top" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Label}">
                        <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                            <Grid.Resources>
                                <LinearGradientBrush x:Key="opacityGradient" StartPoint="0,0" EndPoint="1,0">
                                    <GradientStop Offset="0" />
                                    <GradientStop Offset="0.4" Color="#FFFFFFFF" />
                                    <GradientStop Offset="0.6" Color="#FFFFFFFF" />
                                    <GradientStop Offset="1" />
                                </LinearGradientBrush>
                            </Grid.Resources>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition Height="Auto" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <Rectangle Grid.RowSpan="3"
                                       HorizontalAlignment="Stretch"
                                       VerticalAlignment="Stretch"
                                       Fill="{TemplateBinding Background}"
                                       Opacity="0.3"
                                       OpacityMask="{StaticResource opacityGradient}" />
                            <Line Opacity="0.6"
                                  OpacityMask="{StaticResource opacityGradient}"
                                  Stroke="{TemplateBinding Background}"
                                  StrokeThickness="2"
                                  X1="0"
                                  X2="{TemplateBinding ActualWidth}" />
                            <ContentPresenter Grid.Row="1"
                                              Margin="{TemplateBinding Padding}"
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                              RecognizesAccessKey="True" />
                            <Line Grid.Row="2"
                                  Opacity="0.6"
                                  OpacityMask="{StaticResource opacityGradient}"
                                  Stroke="{TemplateBinding Background}"
                                  StrokeThickness="2"
                                  X1="0"
                                  X2="{TemplateBinding ActualWidth}" />
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

使い方

  1. Labelに↑に書いたStyleを適用
  2. LabelのBackgroundプロパティでボーダーと背景色を設定
  3. LabelのPaddingプロパティで、文字とボーダーまでの距離を調整

適用結果

こんな風に表示されます。

白背景+青いボーダー

f:id:minami_SC:20140114015640p:plain

        <Label Margin="20"
               HorizontalAlignment="Center"
               VerticalAlignment="Top"
               Background="Blue"
               FontSize="20"
               Padding="100,10"
               Style="{DynamicResource GradientBorderLabelStyle}">
            <TextBlock>
                <Run Text="ControlTemplateを使って" />
                <LineBreak />
                <Run Text="文字列を装飾" />
            </TextBlock>
        </Label>
黒背景+白いボーダー

f:id:minami_SC:20140114015655p:plain

        <Label Margin="20"
               HorizontalAlignment="Center"
               VerticalAlignment="Top"
               Background="White"
               Foreground="White"
               FontSize="20"
               Content="黒背景で白のグラデーション"
               Padding="20,10"
               Style="{DynamicResource GradientBorderLabelStyle}" />
背景画像+白いボーダー

f:id:minami_SC:20140114015705p:plain

        <Label Margin="20"
               HorizontalAlignment="Center"
               VerticalAlignment="Top"
               Background="White"
               Foreground="White"
               FontSize="20"
               Content="背景画像+白のボーダー"
               Padding="50,10"
               Style="{DynamicResource GradientBorderLabelStyle}" />