2010-12-12 4 views
9

ボタンの背景をLightGreenに変更し、マウスカーソルをマウスカーソルの上に移動すると、Greenを押したときにDarkGreenに変更することができます。次のXAMLが私の最初の試みです:WPFのボタン背景をエアロでオーバーライドする

<Window x:Class="ButtonMouseOver.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <Button Background="LightGreen"> 
     Hello 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

しかし、これはうまくいきません。私たちはゴールへの道のりの1/3しかありません。はい、ボタンは薄緑色になりますが、上にマウスを置くか押すと、それぞれのボタンの状態に応じて標準のAeroクロムが表示されます。

... 
    <Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
      Background="LightGreen"> 
     Hello 
     <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" 
      x:Name="Chrome" Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}" 
      RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" 
      > 
      <ContentPresenter Margin="{TemplateBinding Padding}" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              RecognizesAccessKey="True" 
              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </Microsoft_Windows_Themes:ButtonChrome> 
     </ControlTemplate> 
     </Button.Template> 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
... 

は、今、私たちは持っているそこに投げ全体frigginのコントロールテンプレートは、 Aero.NormalColor.xamlから持ち上げ:あきらめたくない、私は次の放蕩を試みます。悲しいかな、これは何も変わりません。次に、 Microsoft_Windows_Themes:ButtonChrome要素から2つの属性( RenderPressedRenderMouseOver)を削除します。それでも、変化はありません。

... 
<Button xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"> 
    Hello 
... 

最後に、我々は進歩を持っている:私は、PresentationFramework.Aeroアセンブリのためだけの名前空間宣言を残して、ボタンのBackground属性の設定を削除します。 IsMouseOverとIsPressedが機能していますが、ボタンの通常の状態(マウスが押されていないか押されていない状態)で、私が削除しているので、緑色の背景がないので、要件の1/3から2/3になりましたボタンのBackgroundプロパティを使用して、他の2つの状態を適用して可視にします。この狂気のXAMLは、私たちの通常のボタンの状態のためのライトグリーンの背景の取得に失敗した後、今、私もそこに背景色をスローするようにスタイルを変更します。最後に、それは意図したとおりに

<Button xmlns... 
    <ControlTemplate... 
    ... 
    </ControlTemplate> 
    <Button.Style> 
     <Style TargetType="Button"> 
     <!-- ##### Normal state button background added ##### --> 
     <Setter Property="Background" Value="LightGreen" /> 
     <!-- ################################################ --> 
     <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
      <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
      <Setter Property = "Background" Value="DarkGreen"/> 
      </Trigger> 
     </Style.Triggers> 
     </Style> 
    </Button.Style> 
    </Button> 

動作します。

Aeroのテーマを使ってボタンを押すだけで、様々な状態(通常、上にかかっている、押された)でボタンの背景色を変更する必要がありますか?たぶん、もし私がそれから2つの属性(RenderMouseOverRenderPressed)を取り除くためにそこに全体のButtonTemplateを含める必要がなければ人生はそれほど悪くないでしょう。

何か助けていただきありがとうございます - 私はウィットの終わりです。

更新:しかし、これ以上のことがあります。

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... 
    RenderMouseOver="{TemplateBinding IsMouseOver}" 
    RenderPressed="{TemplateBinding IsPressed}" ... 

:代わりにRenderMouseOverとRenderPressedは、単にからそれらを変更、コントロールテンプレートから属性を削除するの...

<Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" ... 
    RenderMouseOver="{Binding IsMouseOver}" 
    RenderPressed="{Binding IsPressed}" ... 

、また、(ボタンのスタイルのトリガーを無視しての)問題を修正。私は問題の根源は、テンプレートバインディングがコンパイル時に(パフォーマンス上の理由から)適用され、通常のバインディングが実行時に適用されるということです。このため、属性がテンプレートバインディングを使用する場合(つまり、元のテンプレートのIsMouseOverおよびIsPressedが代わりに使用される場合)、個々のボタンからのスタイルトリガーからのバインディングは使用されません。

上記のすべてを言って、ここでは、元のコントロールテンプレートを保ちながら、エアロでボタンの背景を変更するための標準的な例です:

<Window x:Class="ButtonMouseOver.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <Button> 
     Hello 
     <Button.Template> 
     <ControlTemplate TargetType="{x:Type Button}"> 
      <Microsoft_Windows_Themes:ButtonChrome SnapsToDevicePixels="true" 
      x:Name="Chrome" Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding IsDefaulted}" 
      RenderMouseOver="{Binding IsMouseOver}" RenderPressed="{Binding IsPressed}" 
      > 
      <ContentPresenter Margin="{TemplateBinding Padding}" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              RecognizesAccessKey="True" 
              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </Microsoft_Windows_Themes:ButtonChrome> 
     </ControlTemplate> 
     </Button.Template> 
     <Button.Style> 
     <Style TargetType="Button"> 
      <Setter Property="Background" Value="LightGreen"/> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
       <Setter Property = "Background" Value="Green"/> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
       <Setter Property = "Foreground" Value="DarkGreen"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </Button.Style> 
    </Button> 
    </Grid> 
</Window> 

これは、ボタンが1つだけので、スタイリングされていることを想定し、もちろんです、そうしないと、テンプレートとスタイルをどこかのリソースセクションに移動することができます。また、ボタンのデフォルト状態のトリガーもありませんが、上記の例に簡単に追加できます(TemplateBindingではなくBindingを使用するようにコントロールテンプレートのRenderDefaulted属性を変更することを忘れないでください)。

誰でも変更する必要があるコントロールテンプレートで唯一の2つの属性バインディングでどのようにオーバーライド TemplateBindingの上の任意の提案を持っている場合は、エアロXAMLの卸売から全体クロム定義を繰り返すことなく、私はすべての耳をしています。

答えて

2

Buttonのデフォルトテンプレートは、独自の図面を実行するButtonChromeを使用します。デフォルトの外観を完全に取り除きたい場合は、ButtonChromeを除いて独自のテンプレートを定義する必要があります。面倒なように聞こえますが、一度だけ行う必要があります。カスタムスタイルをリソースディクショナリに入れて、StaticResourceと参照するだけです。スタイルのキーとして{x:Type Button}x:Key属性)を使用して、アプリケーションのすべてのボタンにスタイルを適用することもできます。

+0

問題は、ボタンの背景を変更したいだけです。 Aeroクロムは、ボタンの通常状態の背景ボタン属性を使用してこれを正しく処理します。しかし、マウスオーバー時にバックグラウンドが直ちに変化し、ボタンが押されたときに、この処理が失敗します。これらの2つの状態でボタンの背景を変更するのは簡単な方法はありません。これは、Button(およびおそらく他の視覚的要素)にBackground属性を持つという全目的を破っています。 –

+0

Backgroundプロパティはすべてのコントロールに共通しているため、とにかくそこにありますが、テンプレートで考慮されることはありません。私はAeroのテーマで問題を再現することができますし、Lunaのテーマにも同様の問題があります。 ButtonChromeは、特定の州のバックグラウンドを考慮していないようです...とにかく、私は標準的なボタンのクロムがカスタマイズされた色を持つように設計されているとは思いません。もしあなたがそれをしたいのであれば、クロムを使わないでください...あなたはそれがなくてもあなた自身のボタンテンプレートを作るのはかなり簡単です。 –

+0

MSDN(Control.Backgroundプロパティ)から:Backgroundプロパティは、コントロールの休止状態にのみ適用されます。コントロールの既定のスタイルは、コントロールの状態が変更されたときの外観を指定します。たとえば、ボタンにBackgroundプロパティを設定した場合、ボタンは押されていないか無効になっているときにのみその値を持ちます。背景のより高度なカスタマイズを持つコントロールを作成する場合は、コントロールのスタイルを定義する必要があります。 –

関連する問題