次の方法で共有


WPFで透明なボタン

質問

2010年10月19日火曜日 17:42

ボタンについて教えてください。
WPFで透明なボタンを作ろうと思いました。

Button button = new Button();
button.Foreground = Brushes.Transparent;
button.Background = Brushes.Transparent;
としましたが、枠線が残っています。
button.BorderBrush = Brushes.Transparent;

Thickness  transparentThickness = new Thickness();
transparentThickness.Bottom = 0;
transparentThickness.Left = 0;
transparentThickness.Right = 0;
transparentThickness.Top = 0;
button.BorderThickness = transparentThickness;
としてもだめでした。
よろしくお願いします。

すべての返信 (12)

2010年10月19日火曜日 20:28 ✅回答済み

提示されたサンプルコードだと、ボタンにフォーカスが無いときは透明になっていると思います。

ボタンにフォーカスがあるときや、クリックされたときも透明のままにしたいのでしょうか?

その場合、ボタンの Template プロパティを差し替える必要があります。ボタンにフォーカスがあるときの枠線や背景色はプロパティでは変更できないので。

 

なかむら(http://d.hatena.ne.jp/griefworker)


2010年10月26日火曜日 8:11 ✅回答済み | 1 票

WPF はまだまだ判っておりませんが、少しチャレンジしてみました。

> http://msdn.microsoft.com/ja-jp/library/cc278069(VS.95).aspx

のサンプルを改修しております。
ControlTemplate を理解し切って直している訳ではないので、まだおかしなところがあるとは思いますが、参考までにどうぞ。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="400">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="Transparent"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver" />
                                    <VisualState x:Name="Disabled" />
                                    <VisualState x:Name="Pressed" />
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" 
                                                             Storyboard.TargetName="FocusVisualElement" 
                                                             Storyboard.TargetProperty="Opacity" To="0"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="Background" CornerRadius="3" Background="Transparent" 
                                    BorderThickness="{TemplateBinding BorderThickness}" 
                                    BorderBrush="{TemplateBinding BorderBrush}">
                                <Grid Background="{TemplateBinding Background}" Margin="1">
                                    <Border Opacity="0" x:Name="BackgroundAnimation" Background="Transparent" />
                                    <Rectangle x:Name="BackgroundGradient" >
                                        <Rectangle.Fill>
                                            <SolidColorBrush Color="Transparent" Opacity="0.25" />
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>
                            </Border>
                            <ContentPresenter
                             x:Name="contentPresenter"
                             Content="{TemplateBinding Content}"
                             ContentTemplate="{TemplateBinding ContentTemplate}"
                             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                             Margin="{TemplateBinding Padding}"/>
                            <Rectangle x:Name="DisabledVisualElement" RadiusX="3" 
                                      RadiusY="3" Fill="#FFFFFFFF" 
                                      Opacity="0" IsHitTestVisible="false" />
                            <Rectangle x:Name="FocusVisualElement" RadiusX="2" 
                                      RadiusY="2" Margin="1" Stroke="#FF6DBDD1" 
                                      StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>
    <Grid>
        <Button Content="Button" Height="80" HorizontalAlignment="Center" 
                Margin="0" Name="button1" 
                VerticalAlignment="Center" Width="140" Click="button1_Click">
        </Button>
    </Grid>
</Window>

ひらぽん http://d.hatena.ne.jp/hilapon/


2010年10月20日水曜日 2:04

なかむらさん、早速のご回答ありがとうございます。
フォーカスが当たっているときには、ラインがあってもよい(ボタンであることがわかるので)のですが、フォーカスが当たっていなくても、依然としてボタンの枠が残っているようです。
枠線はグレーで角丸、フォーカスがあたると、グレーの内側に山吹色のラインで強調表示されます。
もう一度プログラムを見直しましたが、どうしても枠線を消せません。


2010年10月20日水曜日 2:39

枠線はグレーで角丸、フォーカスがあたると、グレーの内側に山吹色のラインで強調表示されます。

もしかして OS は Windows XP でしょうか?

 

なかむら(http://d.hatena.ne.jp/griefworker)


2010年10月20日水曜日 13:30

あ。そうです。環境について書いていませんでした。
OSはWindowsXP SP3で、C#2010Expressを使用しております。
ひっとして、ということは、XPではそういう制限があるってことでしょうか?


2010年10月20日水曜日 14:18

ひっとして、ということは、XPではそういう制限があるってことでしょうか?

別にそう言うわけではありませんが、Luna テーマの ButtonChrome は BorderBrush なんか気にせず色つき枠を描画しちゃうみたいですね。

初めのなかむらさんのレスにあるように、Template を差し替える必要があるでしょう。取り敢えず、ControlTemplate には Grid の中に HorizontalAlignment/VerticalAlignment を Center にした ContentPresenter を置くだけにしてみて、そこから不足を補うように色々弄ってみて下さい。。


2010年10月20日水曜日 15:08

Hongliangさん、ありがとうございました。
早速試してみたいのですが、素朴な質問で恐縮です。
Templateはどこにあるのでしょう?


2010年10月20日水曜日 15:17

Button のプロパティです。


2010年10月20日水曜日 23:47

Button の Template プロパティに 設定する ControlTemplate の内容は、下記のサンプルを改良するといいです。

http://msdn.microsoft.com/ja-jp/library/cc278069(VS.95).aspx

サンプルは Silverlight ですが、WPF も;たようなものです。

試してはいませんが、Background という名前のついた Border を普段透明にしておけば、お望みの動作に近くなると思います。色々と試行錯誤してみてください。

なかむら(http://d.hatena.ne.jp/griefworker)


2010年10月25日月曜日 15:07

やっとテストできる環境を用意してテストを始めました。
いきなり.csはむずかしそうなので、xamlでボタンを処理しています。
ボタンを配置して、ボタンのプロパティを見てみました。
すると、Templateの項目があり、リソースプロパティエディターとなっていますが、これを開くと、「現在のプロパティの型に一致するリソースがありません」とあるだけで、取りつく島がありません。
Templateを差し替えるとは、どこでどれをどのように作業するものなのでしょう?
ControlTemplateがどこにあるのかもよくわからないでいます。
現在のプロジェクトを対象に検索してもヒットしないですし。


2010年10月25日月曜日 15:08

Silverlightのサンプルを見てみました。
xamlなので、そのまま組み込めばよいのかどうかわかりませんが、とりあえず組み込んでみて、Gridをひとつにしたところ(当然(?)、多数(10個)のエラーが。

<Window x:Class="ボタン.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="144" Width="204"
BorderThickness="0"
>
    <Style TargetType="Button">
        <Setter Property="Background" Value="#FF1F3B53"/>
        <Setter Property="Foreground" Value="#FF000000"/>
        <Setter Property="Padding" Value="3"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFA3AEB9" Offset="0"/>
                    <GradientStop Color="#FF8399A9" Offset="0.375"/>
                    <GradientStop Color="#FF718597" Offset="0.375"/>
                    <GradientStop Color="#FF617584" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>//これを消してみた。
                        <Border x:Name="Background" CornerRadius="3" Background="White" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                            <Grid Background="{TemplateBinding Background}"  Margin="1">
                                <Border Opacity="0"  x:Name="BackgroundAnimation" Background="#FF448DCA" />
                                <Rectangle x:Name="BackgroundGradient" >
                                    <Rectangle.Fill>
                                        <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                                            <GradientStop Color="#FFFFFFFF" Offset="0" />
                                            <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                                            <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                                            <GradientStop Color="#C6FFFFFF" Offset="1" />
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                            </Grid>//これも消してみた。
                        </Border>
                        <ContentPresenter
                              x:Name="contentPresenter"
                              Content="{TemplateBinding Content}"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              Margin="{TemplateBinding Padding}"/>
                        <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
                        <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Grid>
        <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="53,28,0,0" Name="button1" VerticalAlignment="Top" Width="75">
            <Button.Background>
                <SolidColorBrush />
            </Button.Background>
            <Button.Foreground>
                <SolidColorBrush />
            </Button.Foreground>
        </Button>
    </Grid>
</Window>

現状でボタンの枠以外は透明です。
道のりは遙かに遠そうですが、この先どうしたらよいかご示唆ください。
よろしくお願いします。


2010年10月26日火曜日 11:41

ひらぽんさん
ありがとうございました。
ボタンの枠線が消えました。
ここ半月ほど悩んでいた悩みをやっと解消できました。
Window.Resourcesとかという書き方は、まったく予想外だったので、ひとりではとうてい無理でした。
重ねて。ありがとうございました。