2014-10-23 2 views
1

내 ControlTemplate 내에서 VisualStateManager를 ToggleButton에 사용하려고합니다. ToggleButton을 선택하면 한 가지 방법으로 보이게하고 선택하지 않을 때는 ToggleButton을 선택합니다. 또한 ToggleButton이 비활성화되었을 때 다른 모양으로 보이기를 원합니다. 내가 가지고있는 문제는 체크되지 않은 VisualState가 Disabled VisualState를 트럼프하고있는 것처럼 보입니다.VisualStateManager VisualGroup 우선 순위

설명서에는 "각 VisualStateGroup에는 상호 배타적 인 VisualState 개체의 컬렉션이 포함되어 있습니다."라는 내용이 나와 있습니다. 좋았지 만 그룹 간 상호 배타성은 어땠습니까?

어쨌든, 여기 내 ControlTemplate입니다. TextBlock이 세 가지 상태 각각에 다른 색상을 사용하도록하려면 어떻게합니까? 선택, 선택 취소 및 사용 중지?

<Style x:Key="GraphToggleButtonStyle" TargetType="{x:Type ToggleButton}"> 
    <Setter Property="BorderThickness" Value="0" /> 
    <Setter Property="Cursor" Value="Hand" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Border Background="Transparent"> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Disabled"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TextBlock" To="Pink" Duration="0" /> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="CheckStates"> 
          <VisualState x:Name="Checked"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TextBlock" To="#3AA5DB" Duration="0" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Unchecked"> 
           <Storyboard> 
            <ColorAnimation Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TextBlock" To="Green" Duration="0" /> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Indeterminate" /> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="Border" CornerRadius="4" Background="{TemplateBinding Background}"> 
         <StackPanel> 
          <TextBlock Name="TextBlock" FontFamily="/Resources/#Entypo" Text="" FontSize="87" Foreground="#909090" HorizontalAlignment="Center" Margin="0,-25,0,0" /> 
          <TextBlock FontFamily="Proxima Nova Rg" Text="Stimulator" FontSize="18" Foreground="{StaticResource BlackBrush}" HorizontalAlignment="Center" Margin="0,12,0,0" /> 
         </StackPanel> 
        </Border> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

답변

3

각 VisualStateGroup이 실제로 사실이다

상호 배타적 VisualState 개체의 컬렉션을 포함합니다. 그러나 여전히 하나의 요구 사항이 있습니다. 각 VisualState 은 동일한 속성에 영향을 주어서는 안됩니다. 이 경우 검사되지 않은 상태와 사용 중지 된 상태가 같은 요소의 동일한 속성 Foreground에 영향을줍니다.

그래서 우리는 이것에 대한 멋진 해결책이 없다고 생각합니다. WPF에서 요소를 스타일링 할 때 실제로 일반적으로 사용되는이 해결 방법이 있습니다. DisabledTextBlock이라는 가짜 요소가 필요합니다.이 요소는 원래 요소 TextBlock이있는 동일한 Grid에 배치해야합니다. Disabled 상태가되면 해당 가짜 요소가 표시되고 원래 요소를 숨기고 Unchecked (또는 Checked) 상태의 모든 효과를 숨기고 Disabled의 효과를 맨 앞에 표시해야합니다. 여기에 작업 코드가 있습니다 :

<ControlTemplate TargetType="{x:Type ToggleButton}"> 
    <Border Background="Transparent"> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="CheckStates"> 
      <!-- unchanged --> 
     </VisualStateGroup> 
     <VisualStateGroup x:Name="CommonStates">        
      <VisualState Name="Disabled"> 
      <Storyboard> 
      <DoubleAnimation Storyboard.TargetProperty="Opacity" 
         Storyboard.TargetName="DisabledTextBlock" To="1" Duration="0" /> 
      </Storyboard> 
      </VisualState>        
     </VisualStateGroup>       
     </VisualStateManager.VisualStateGroups> 
     <Border x:Name="Border" CornerRadius="4" Background="{TemplateBinding Background}"> 
     <StackPanel> 
      <Grid> 
      <TextBlock Name="TextBlock" FontFamily="/Resources/#Entypo" Text="" 
         FontSize="87" Foreground="#909090" HorizontalAlignment="Center" 
         Margin="0,-25,0,0" Background="Transparent"/> 
      <!-- the fake element --> 
      <TextBlock Name="DisabledTextBlock" Opacity="0" 
         FontFamily="{Binding FontFamily, ElementName=TextBlock}" 
         Text="{Binding Text,ElementName=TextBlock}" 
         FontSize="{Binding FontSize,ElementName=TextBlock}" 
         Foreground="Pink" HorizontalAlignment="Center" 
         Margin="{Binding Margin, ElementName=TextBlock}" 
         Background="Transparent" 
         FontStyle="{Binding FontStyle,ElementName=TextBlock}" 
         FontWeight="{Binding FontSize, ElementName=TextBlock}"/> 
      </Grid> 
      <TextBlock FontFamily="Proxima Nova Rg" Text="Stimulator" FontSize="18" 
         Foreground="Black" HorizontalAlignment="Center" Margin="0,12,0,0"/> 
     </StackPanel> 
     </Border> 
    </Border> 
</ControlTemplate> 

당신은 몇 가지 새로운 요구 사항이있을 수 있습니다. 그것이 제가 생각하는 유일한 해결책입니다.

+1

당신은 그 사람입니다. 나는 DisabledTextBlock을 숨기기 위해서 Normal 상태를 추가해야했습니다. 어쨌든, 나는 효과를 얻기 위해 여분의 요소를 추가 할 필요가 없었 으면 좋겠다. –