首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VisualStateManager VisualGroup优先

VisualStateManager VisualGroup优先
EN

Stack Overflow用户
提问于 2014-10-23 03:08:49
回答 1查看 1.3K关注 0票数 3

我正在尝试使用ControlTemplate中的ControlTemplate作为ToggleButton。我希望ToggleButton在选中时看上去是一种方式,而在未选中时则是另一种方式。当ToggleButton被禁用时,我也希望它看起来不同。我遇到的问题是,未经检查的VisualState似乎超过了禁用的VisualState。

文档指出:“每个VisualStateGroup包含一个相互排斥的VisualState对象集合。”不错,但是团体之间的相互排他性呢?

不管怎样,这是我的ControlTemplate。如何让TextBlock对这三种状态使用不同的颜色:选中、未检查和禁用?

代码语言:javascript
复制
<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>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-23 04:26:14

每个VisualStateGroup包含一个相互排斥的VisualState对象集合。

这其实是真的。但是,还有一个要求,即每个VisualState 都不应该影响相同的属性。在这种情况下,未检查状态和禁用状态会影响相同元素的相同属性Foreground

所以我不认为我们能有任何优雅的解决方案。我们只有这样的工作(事实上,这是在WPF中的样式元素时常用的)。我们需要一些名为DisabledTextBlock的假元素,这应该与原始元素TextBlock放在同一个网格中。一旦禁用状态出现,就应该显示该假元素并隐藏原始元素,并隐藏Unchecked (或Checked)状态的所有效果,并将Disabled的效果带到最前面。以下是工作代码:

代码语言:javascript
复制
<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>

您可能有一些新的要求,但这里的想法是明确的。我想这是唯一的解决办法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26520661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档