Übergeordnete Schaltfläche hintergrund in WPF auf Aero

So, der Wunsch ist einfach, ändern Sie eine Taste der hintergrund Hellgrün, Grün, wenn der Mauszeiger darüber bewegt wird und Dunkelgrün, wenn Sie gedrückt wird. Der folgende XAML-Code ist mein Erster Versuch:

<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>

Aber leider funktioniert das nicht. Wir sind nur 1/3 der Weg in Richtung Ziel. Ja, die Taste wird grün, aber sobald man mit dem Mauszeiger oder drücken Sie Sie erhalten standard-Aero Chrom für den jeweiligen button Staaten. Wollte nicht aufgeben, ich Versuch die folgenden Ausschweifungen:

...
    <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>
...

Nun haben wir die ganze verdammte Kontrolle Vorlage geworfen, es hob aus Aero.NormalColor.xaml. Ach, das ändert nichts. Ich gehe dann über das entfernen von zwei Parametern (RenderPressed und RenderMouseOver) aus der Microsoft_Windows_Themes:ButtonChrome element. Noch gibt es keine änderung. Ich entfernen Sie dann die Einstellung mit der Schaltfläche Background - Attribut, so dass nur die namespace-Deklaration für die PresentationFramework.Aero Montage:

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

Schließlich haben wir den Fortschritt. Wir haben eben von 1/3 der Anforderungen, die zu 2/3 von der Art und Weise, mit der IsMouseOver-und IsPressed arbeiten, aber kein Licht grün hintergrund, während Sie die Taste normalen Zustand (nicht moused über, oder gedrückt), da habe ich entfernt, die Hintergrund-Eigenschaft der Schaltfläche, um die beiden anderen Staaten angewendet und sichtbar sein. Jetzt, nach diesem wahnsinnigen XAML ausfällt, um uns die Hellgrünen hintergrund, die für den normalen Knopf, ändern Sie den Stil zu werfen, die Hintergrundfarbe dort auch:

  <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>

Schließlich, es funktioniert wie vorgesehen.

Bin ich verrückt, oder sind diese (und mehr), die Reifen, die Sie haben, um durch zu gehen mit einem Aero-Design zu ändern Sie einfach eine Schaltfläche Hintergrundfarbe in einigen verschiedenen Zuständen (normal, schwebte vorbei, gedrückt)? Vielleicht, das Leben wäre nicht so schlimm, wenn ich nicht das gesamte dang ButtonTemplate dort nur entfernen Sie die zwei Attribute (RenderMouseOver und RenderPressed) aus.

Danke für jede Hilfe - ich bin mit Latein am Ende.

Update: Aber warten Sie, es gibt mehr zu diesem. Anstelle des Entfernens der RenderMouseOver und RenderPressed Attribute aus der Steuerelement-Vorlage, einfach, Sie zu ändern von:

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

zu:

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

..., behebt auch das problem (bei Missachtung der button-Stil-Trigger). Ich denke, die Wurzel des Problems ist, dass die Vorlage Bindungen angewendet werden zur compile-Zeit (aus performance-Gründen), während normale Bindungen zur Laufzeit angewendet. Weil dieses, die Bindungen von der style-Trigger aus der die einzelnen Tasten werden nicht verwendet, wenn Attribute mithilfe von template-Bindungen (d.h., die IsMouseOver-und IsPressed von der ursprünglichen Vorlage werden stattdessen verwendet).

Gesagt, alle der oben genannten, hier ist das kanonische Beispiel für die änderung eines button-hintergrund im Aero-unter Beibehaltung seiner original-Vorlage:

<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>

Dies ist natürlich unter der Annahme, dass nur ein Knopf ist so gestylt, da sonst die Vorlage und Stil können verschoben werden, in eine Ressourcen-Abschnitt irgendwo. Es gibt auch keine trigger für die Standard-Status der Schaltfläche, aber es ist sehr einfach das obige Beispiel (vergessen Sie nicht, ändern Sie die RenderDefaulted-Attribut in das control-template für die Bindung statt TemplateBinding).

Wenn jemand irgendwelche Vorschläge auf, wie überschreiben die TemplateBinding mit Bindung nur für die beiden Attribute in der steuerelementvorlage, die sich ändern müssen, ohne zu wiederholen, der gesamte Chrom definition der aero-xaml-Großhandel, bin ich alle Ohren.

Schreibe einen Kommentar