37392


記述するべき内容が不足していたら申し訳ありません。  
  

* * *

### やりたいこと

ボタンの色によって文字色を同時に変える方法を模索しています。  
  

* * *

### 現状

今まではControlTemplateで、GridとRectangleでButtonの見た目を作っていました。  
そしてButtonの上にTextblockを置いてButtonを実装しています。

・Control.Button.xaml(一部)

[code]

    <ControlTemplate x:Key="RectangleButton" TargetType="Button">
        <Grid IsEnabled="{TemplateBinding IsEnabled}">
            <Rectangle Name="FillRectangle" Fill="{StaticResource AccentColorBrush}"
                       Height="30" Width="128"/>
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            <VisualStateManager.VisualStateGroups>
            <!--省略-->
    
    <!--ボタンスタイル-->
    <Style x:Key="DialogButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Template" Value="{StaticResource RectangleButton}"/>
        <Setter Property="Margin" Value="5,0,0,0"/>
    </Style>
    
[/code]

・TestViewA.xaml(一部)

[code]

    <!--リソース-->
    <UserControl.Resources>
        <Style TargetType="TextBlock" BasedOn="{StaticResource DefaultDialogTextStyleKey}">
            <Setter Property="Width" Value="120"/>
        </Style>
    
        <Style TargetType="Button" BasedOn="{StaticResource DialogButtonStyle}"/>
    
        <Style x:Key="BottomStackPanel" TargetType="StackPanel">
            <Setter Property="Orientation" Value="Horizontal"/>
            <Setter Property="Margin" Value="0,5,0,5"/>
        </Style>
    </UserControl.Resources>
    
    <!--一部省略-->
        <Grid Grid.Row="2" Grid.Column="0">
            <StackPanel Style="{StaticResource BottomStackPanel}" HorizontalAlignment="Right">
                <Button Command="{Binding SaveCommand}"
                        IsEnabled="{Binding HasChanged}"
                        Name="SaveButton">
                    <TextBlock Text="保存"
                               Style="{StaticResource TextButtonStyleKey}"/>
                </Button>
                <Button Command="{Binding CancelCommand}"
                        IsEnabled="{Binding HasChanged}"
                        Name="CancelButton">
                    <TextBlock Text="キャンセル"
                               Style="{StaticResource TextButtonStyleKey}"/>
                </Button>
            </StackPanel>
        </Grid>
    
[/code]

  

今回、「機能のON/OFFで見た目の色が変わるトグルボタン」を実装しようとしたのですが、  
現在、ボタン上に配置している文字の色が別のスタイル(白色)を設定している為、  
ボタンの色が明るくなると文字が見づらいです。  
その為、 **トグルボタンの色によって文字色も変えたいと思ったのですが、  
どう書けばいいか分からないのが現状です。**  
実際に実装するViewにTriggerでゴリゴリ書こうかと思ったのですが、  
複数実装予定な為、テンプレートでまとめて見た目を作れないかなと思った次第です。  
「この書き方じゃ無理、こっちの方がスマートで簡単な実装」等あれば  
喜んでそちらに切り替えようと思っております。

  

### 実装の為に追加したコード

・Control.Button.xaml(一部)

[code]

    <!--トグルボタンテンプレート-->
    <ControlTemplate x:Key="ToggleButton" TargetType="ToggleButton">
        <Grid IsEnabled="{TemplateBinding IsEnabled}">
            <Rectangle Name="FillRectangle" Height="30" Width="128"
                       Fill="{StaticResource AccentColorBrush}"
                       Stroke="{StaticResource AccentColorBrush}" StrokeThickness="3"/>
            <!--
            このTextBlockのTextを実装側で変えられたらなあ、と思います。
            苦し紛れにContentPresenterを置いてますが意味が無い…
            -->
            <TextBlock Name="ToggleButtonText" Margin="0,0,0,1" FontSize="15" Foreground="White" FontWeight="Normal"/>
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
        <ControlTemplate.Triggers>
            <!--
            他はVisualStateManagerで書いているのですが、
            IsCheckedとIsMouseOverを同時に見たいのでこれだけMultiTriggerで書いています。
            個人的には気持ち悪いとは思うのですがこういうものですかね？
            -->
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="False"/>
                    <Condition Property="IsMouseOver" Value="False"/>
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource AccentColorBrush}"/>
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource AccentColorBrush}"/>
                <Setter TargetName="ToggleButtonText" Property="Foreground" Value="White"/>
            </MultiTrigger>
    
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="False"/>
                    <Condition Property="IsMouseOver" Value="True"/>
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource StringColorBrush}"/>
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource StringColorBrush}"/>
                <Setter TargetName="ToggleButtonText" Property="Foreground" Value="White"/>
            </MultiTrigger>
    
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="True"/>
                    <Condition Property="IsMouseOver" Value="True"/>
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource LightGrayBrush}"/>
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource StringColorBrush}"/>
                <Setter TargetName="ToggleButtonText" Property="Foreground" Value="{StaticResource StringColorBrush}"/>
            </MultiTrigger>
    
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="True"/>
                    <Condition Property="IsMouseOver" Value="False"/>
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource AccentColorBrush4}"/>
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource AccentColorBrush}"/>
                <Setter TargetName="ToggleButtonText" Property="Foreground" Value="{StaticResource AccentColorBrush}"/>
            </MultiTrigger>
    
        </ControlTemplate.Triggers>
    </ControlTemplate>
    
    <!--トグルボタンスタイル-->
    <Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="Template" Value="{StaticResource ToggleButton}"/>
        <Setter Property="Margin" Value="2,2,2,2"/>
    </Style>
    
[/code]

・TextViewB.xaml(一部)

[code]

    <UserControl.Resources>
        <ResourceDictionary>
            <Style TargetType="TextBlock" BasedOn="{StaticResource DefaultDialogTextStyleKey}" />
            <Style TargetType="ToggleButton" BasedOn="{StaticResource ToggleButtonStyle}"/>
    
            <Style x:Key="BaseStackPanel" TargetType="StackPanel">
                <Setter Property="Orientation" Value="Horizontal"/>
            </Style>
        </ResourceDictionary>
    </UserControl.Resources>
    
    <StackPanel DockPanel.Dock="Right"
                Style="{StaticResource BaseStackPanel}"
                VerticalAlignment="Top" Margin="0,10,20,0"
                HorizontalAlignment="Right">
    
        <ToggleButton IsEnabled="{Binding IsAreaEnable}"
                      Command="{Binding CreateArea}"
                      IsChecked="{Binding EnableToggleButton}"">
            <!--
            Buttonはクリックするとデザインが変わりますが、
            ↓のTextBlockの色が変わらない
            -->
            <TextBlock Name="ToggleButtonText" Text="テスト"/>
        </ToggleButton>
    </StackPanel>
    
[/code]

  

* * *

  

皆様のお知恵をお貸しいただければと思います。  
どうぞよろしくお願いいたします。

  

### 環境

・Microsoft Visual Studio 2013 Express for Windows  
・.NET Framework 4.5.1  
・C# 5.0


CC BY-SA 3.0
2017-08-21T23:58:27.033
37388
2017-08-22T06:51:51.280
2017-08-22T04:31:41.503
question
c# wpf xaml
ボタンの色によって文字色を変える


`TextBlock.Foreground`プロパティはアンビエントプロパティですので、明示しない限り暗黙に上位要素の設定を継承します。ですので`ContentPresenter`を内包する要素の`Control.Foreground`を指定すればスタイルを外部から反映することができます。

ですので`ControlTemplate.Triggers`の`<Setter TargetName="ToggleButtonText"
Property="Foreground"
/>`から`TargetName`を削除し、単純に`ToggleButton`自体のプロパティを変更するようにしてください。

[code]

    <ControlTemplate TargetType="ToggleButton">
        <Grid IsEnabled="{TemplateBinding IsEnabled}">
            <Rectangle Name="FillRectangle" Height="30" Width="128"
                        Fill="{StaticResource AccentColorBrush}"
                        Stroke="{StaticResource AccentColorBrush}" StrokeThickness="3" />
    
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
        <ControlTemplate.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="False" />
                    <Condition Property="IsMouseOver" Value="False" />
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource AccentColorBrush}" />
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource AccentColorBrush}" />
                <Setter  Property="Foreground" Value="White" />
            </MultiTrigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="False" />
                    <Condition Property="IsMouseOver" Value="True" />
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource StringColorBrush}" />
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource StringColorBrush}" />
                <Setter   Property="Foreground" Value="White" />
            </MultiTrigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="True" />
                    <Condition Property="IsMouseOver" Value="True" />
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource LightGrayBrush}" />
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource StringColorBrush}" />
                <Setter   Property="Foreground" Value="{StaticResource StringColorBrush}" />
            </MultiTrigger>
    
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsChecked" Value="True" />
                    <Condition Property="IsMouseOver" Value="False" />
                </MultiTrigger.Conditions>
                <Setter TargetName="FillRectangle" Property="Fill" Value="{StaticResource AccentColorBrush4}" />
                <Setter TargetName="FillRectangle" Property="Stroke" Value="{StaticResource AccentColorBrush}" />
                <Setter   Property="Foreground" Value="{StaticResource AccentColorBrush}" />
            </MultiTrigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    
[/code]

## 追記

上記でプロパティが反映されないということですので、`DefaultDialogTextStyleKey`に`Foreground`の指定があって継承より優先されているのだと思います。

でしたら`Style`が反映されないようにするか、`RelativeSource`を使用したバインドを追加するかのどちらかだと思います。

`Style`を上書きするには`Resources`の既定のスタイルを再定義するか、

[code]

    <ToggleButton.Resources>
        <Style TargetType="TextBlock" />
    </ToggleButton.Resources>
    
[/code]

直接`Style`を指定するなどしてください。

[code]

    <TextBlock Style="{x:Null}" />
    
[/code]

`RelativeSource`の場合は以下のようになりますが、プロパティの数だけ該当要素に指定をしないといけないことに注意してください。

[code]

    <TextBlock
        Foreground="{Binding RelativeSource={RelativeSource AncestorType=Control}, Path=Foreground}" />
    
[/code]


CC BY-SA 3.0
2017-08-22T03:27:57.513
37392
2017-08-22T06:51:51.280
2017-08-22T06:51:51.280
5750
5750
37388
answer