2017-12-26 22 views
0

コントロールテンプレートを使用してトグルボタンにカスタムスタイルを適用しました。私はデフォルトの状態、チェックされた状態とマウスのホバーのために異なる背景色と境界線を持っています。問題は、チェックされた状態にマウスポインタを置くと、実際にトグルボタンがチェックされているにもかかわらず、ボタンがチェックされていない(既定の状態の外観に)ようにスタイルがリセットされることです。あなたは、それは意志、あなたはそれの上に置いて、それを残しますがあれば、それは緑の境界線と異なる背景色を取得することがわかりますトグルボタンをクリックする場合はここでWPFトグルボタンのスタイルは、ホバーの影響を受けます。

は私のコードは

<Style x:Key="MenuItem" TargetType="ToggleButton"> 
    <Setter Property="Background" Value="Transparent"/> 
    <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter Property="Cursor" Value="Hand"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

<ControlTemplate x:Key="MenuButton" TargetType="{x:Type ToggleButton}"> 

    <Border x:Name="border" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderThickness="4,0,0,0"> 
     <StackPanel x:Name="MenuItemContainer" Orientation="Horizontal" Height="46" Margin="14,0,0,0" Background="Transparent"> 
      <TextBlock x:Name="icon" Grid.Column="0" VerticalAlignment="Center" FontFamily="{StaticResource FontAwesome}" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Tag}" Margin="0,0,6,0"/> 
      <TextBlock x:Name="menuText" VerticalAlignment="Center" Foreground="#a7b1c2" FontSize="13" Text="{TemplateBinding Property=ContentControl.Content}"/> 
     </StackPanel> 

     <VisualStateManager.VisualStateGroups> 

      <VisualStateGroup x:Name="CommonStates"> 
       <VisualState x:Name="MouseOver"> 
        <Storyboard> 
         <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" /> 
         <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/> 

         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border"> 
          <DiscreteObjectKeyFrame KeyTime="0"> 
           <DiscreteObjectKeyFrame.Value> 
            <SolidColorBrush Color="{StaticResource ColorMenuItemBg}" /> 
           </DiscreteObjectKeyFrame.Value> 
          </DiscreteObjectKeyFrame> 
         </ObjectAnimationUsingKeyFrames> 
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border"> 
          <DiscreteObjectKeyFrame KeyTime="0"> 
           <DiscreteObjectKeyFrame.Value> 
            <SolidColorBrush Color="{StaticResource ColorMenuItemBorderHover}"/> 
           </DiscreteObjectKeyFrame.Value> 
          </DiscreteObjectKeyFrame> 
         </ObjectAnimationUsingKeyFrames> 
        </Storyboard> 
       </VisualState> 
       <VisualState x:Name="Normal"/> 
      </VisualStateGroup> 

      <VisualStateGroup x:Name="CheckStates"> 
       <VisualState x:Name="Checked"> 
        <Storyboard> 
         <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="border"> 
          <EasingThicknessKeyFrame KeyTime="0" Value="4,0,0,0"/> 
         </ThicknessAnimationUsingKeyFrames> 
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush)" Storyboard.TargetName="border"> 
          <DiscreteObjectKeyFrame KeyTime="0"> 
           <DiscreteObjectKeyFrame.Value> 
            <SolidColorBrush Color="{StaticResource ColorMenuItemBorder}"/> 
           </DiscreteObjectKeyFrame.Value> 
          </DiscreteObjectKeyFrame> 
         </ObjectAnimationUsingKeyFrames> 
         <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" /> 
         <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/> 

         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="border"> 
          <DiscreteObjectKeyFrame KeyTime="0"> 
           <DiscreteObjectKeyFrame.Value> 
            <SolidColorBrush Color="{StaticResource ColorMenuItemBg}"/> 
           </DiscreteObjectKeyFrame.Value> 
          </DiscreteObjectKeyFrame> 
         </ObjectAnimationUsingKeyFrames> 
        </Storyboard> 
       </VisualState> 
       <VisualState x:Name="Unchecked"/> 
      </VisualStateGroup> 


     </VisualStateManager.VisualStateGroups> 
    </Border> 
</ControlTemplate> 

<StackPanel> 
      <ToggleButton Tag="&#xf015;" Content="Home" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}" /> 

      <ToggleButton Tag="&#xf1fe;" Content="Reporting" Template="{StaticResource MenuButton}" Style="{StaticResource MenuItem}"/> 
</StackPanel> 

ですデフォルトのボタンとして表示されるようです。

私はここで何が欠けていますか?

ありがとうございました!

答えて

0

テンプレートに2つのVisualtStateGroupsを定義しました。この方法では、ToggleButtonの2つのアクティブな状態(グループごとに1つずつ)が常に得られます。問題は、2つの異なるグループ内のVisualStatesから同じオブジェクトプロパティを設定していることです。 ToggleButtonをチェックしてマウスがボタンを離れると、コントロールはアクティブなVisualStateをすべてのグループに対して更新します。あなたの設定Border.BackgroundBorder.BorderBrush両方のグループのアクティブ状態から、最後に適用された状態が勝ちます(あなたのケースではCommonStates/Normal)。

この問題を解決するには、mulitplyグループから同じプロパティを設定しないようにしてください。例えば、ボーダーバックグラウンドではなく、MouseOver-StateでStackpanelの背景を設定することができます。この方法では、ToggleButtonは、 "CommonState/Normal" -Stateがボーダーの背景をリセットしないため、マウスがマウスを離れるとチェックされたままになります。

    <VisualStateGroup x:Name="CommonStates"> 
         <VisualState x:Name="MouseOver"> 
          <Storyboard> 
           <ColorAnimation Storyboard.TargetName="menuText" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0" /> 
           <ColorAnimation Storyboard.TargetName="icon" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" To="White" Duration="0:0:0"/> 

           <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background)" Storyboard.TargetName="MenuItemContainer"> 
            <DiscreteObjectKeyFrame KeyTime="0"> 
             <DiscreteObjectKeyFrame.Value> 
              <SolidColorBrush Color="{StaticResource ColorMenuItemBg}" /> 
             </DiscreteObjectKeyFrame.Value> 
            </DiscreteObjectKeyFrame> 
           </ObjectAnimationUsingKeyFrames> 

          </Storyboard> 
         </VisualState> 
         <VisualState x:Name="Normal"/> 
        </VisualStateGroup> 

希望がありました。

+0

ありがとうございました。この問題を解決しただけでなく、WPFがさまざまなVisual State Groupsに対してどのように動作するかについても説明しました。あなたは私に説明してください。複数のVisual State Groupsを持つことは悪い習慣ですか?同じプロパティ値を設定しないように注意する必要がありますか?ベストプラクティスは何ですか? –

+0

あなたはすごいです!テンプレート内に複数のVisualStateGroupを置くことは、まったく問題ありません。実際、wpfコントロールのデフォルトスタイルを調べると、それらのほとんどに3つ以上のStateGroupが定義されています。状態が同じプロパティを設定していないことを確認してください。 –

関連する問題