如何在重新启用后保持ToggleButton状态

时间:2016-12-05 14:09:08

标签: c# wpf-controls

我希望在重新启用ToggleButton后保持ToggleButton状态。但它会一直关闭。
当椭圆激活时,这是我的ToggleButton:

enter image description here

打开ToggleLock时:

enter image description here

解锁后:

enter image description here

它的颜色错了。它必须变成绿色。
我的代码和样式:

<!--EllipseToggleButton Style-->
<Style TargetType="ToggleButton"
  x:Key="EllipseToggleButton"> 
  <Setter Property="Margin"
  Value="20 10 0 10" />
  <Setter Property="Height"
  Value="30" />
  <Setter Property="VerticalAlignment"
  Value="Top" />
  <Setter Property="IsTabStop"
  Value="False" />
  <Setter Property="FocusVisualStyle"
  Value="{x:Null}" />
  <Setter Property="Template">
  <Setter.Value>
  <ControlTemplate TargetType="{x:Type ToggleButton}">
   <Grid Name="contain">
   <VisualStateManager.VisualStateGroups>
   <VisualStateGroup x:Name="CommonStates">
   <VisualState x:Name="Normal" />
   <VisualState x:Name="Disabled">
   <Storyboard>
   <ColorAnimation Storyboard.TargetName="icon"
   Storyboard.TargetProperty="(Path.Fill).(Color)"
   To="#3D727272"
   Duration="0" />
   </Storyboard>
   </VisualState>
   </VisualStateGroup>
   <VisualStateGroup x:Name="CheckedStates">
   <VisualState x:Name="Checked">
   <Storyboard>
   <ColorAnimation x:Name="IconCheckedColorAni"
   Storyboard.TargetName="icon" Duration="0"
   Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
   To="#FF68E80F" />
   </Storyboard>
   </VisualState>
   <VisualState x:Name="Unchecked" />
   </VisualStateGroup>
   </VisualStateManager.VisualStateGroups>
   <Ellipse Name="icon"
   Height="24"
   Width="24"
   Stretch="Uniform"
   VerticalAlignment="Center"
   Cursor="Hand"
   Fill="{TemplateBinding Background}" />
   </Grid>
  </ControlTemplate>
  </Setter.Value>
  </Setter>
</Style>

主窗口:

<StackPanel Orientation="Horizontal">
  <ToggleButton x:Name="ToggleLock"
  Content="Lock"
  Width="100"
  Margin="20 10 0 10"
  VerticalAlignment="Top"
  Height="30" />
  <ToggleButton Style="{StaticResource EllipseToggleButton}"
  IsEnabled="{Binding ElementName=ToggleLock, Path=IsChecked, Converter={StaticResource InBConv}}"
  Background="Red" />
</StackPanel>

转换器:

class InvertBoolConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    if (value != null && value is bool)
    {
      return !(bool)value;
    }
    return false;
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

4 个答案:

答案 0 :(得分:1)

ToggleButton在禁用时会保留其IsChecked值。但是,重新启用它时,视觉效果不匹配:当您取消切换锁定时,激活CommonStates.Normal视觉状态组,我可以告诉它,重置默认值。名为Ellipse的{​​{1}}:

icon

......让它变红。您会发现需要单击省略号两次才能使其再次变为绿色。

由于省略号切换按钮未更改其Fill="{TemplateBinding Background}" 值,因此不会调用IsChecked可视状态故事板。

我还没有找到任何方法在XAML中修复此问题(尝试重新排序触发器,明确写出所有状态等等),但是您可以通过强制从代码隐藏中更改CheckedStates状态来解决此问题:

IsChecked

...使用以下事件处理程序:

<StackPanel Orientation="Horizontal">
    <ToggleButton x:Name="ToggleLock"
        Content="Lock"
        Width="100"
        Margin="20 10 0 10"
        VerticalAlignment="Top"
        Height="30"
        Checked="OnChecked"
        Unchecked="OnChecked" />
    <ToggleButton
        x:Name="toggleButton"
        Style="{StaticResource EllipseToggleButton}"
        IsEnabled="{Binding ElementName=ToggleLock, Path=IsChecked, Converter={StaticResource InBConv}}"
        Background="Red" />
</StackPanel>

我不知道这是最好的解决方案,但确实有效,可以作为进一步调查的起点。

答案 1 :(得分:1)

我认为你的问题的根源是为2个不同的VisualStateGroup使用相同的元素。正如您所看到的,here有一个名为“DisabledVisualElement”的元素来处理“已禁用”VisualState,该元素与处理“CheckStates”VisualStateGroup的元素分开。

接下来,我将另一个名为“iconDisabled”的椭圆添加到 Opacity =“0”的模板中,其值在“已禁用”中更改为“1”的VisualState。另外,我在您的“图标”中添加了 Opacity =“1”,并在“已禁用”的VisualState中更改为“0”

以下是修改后的样式代码

    <Style TargetType="ToggleButton"
           x:Key="EllipseToggleButton">
        <Setter Property="Margin"
                Value="20 10 0 10" />
        <Setter Property="Height"
                Value="30" />
        <Setter Property="VerticalAlignment"
                Value="Top" />
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="FocusVisualStyle"
                Value="{x:Null}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid Name="contain">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0"
                                                         Storyboard.TargetName="iconDisable"
                                                         Storyboard.TargetProperty="Opacity" To="1" />
                                        <DoubleAnimation Duration="0"
                                                         Storyboard.TargetName="icon"
                                                         Storyboard.TargetProperty="Opacity" To="0" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="CheckedStates">
                                <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <ColorAnimation x:Name="IconCheckedColorAni"
                                                        Storyboard.TargetName="icon" Duration="0"
                                                        Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
                                                        To="#FF68E80F" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unchecked">
                                    <Storyboard>
                                        <ColorAnimation x:Name="IconUncheckedColorAni"
                                                        Storyboard.TargetName="icon" Duration="0"
                                                        Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
                                                        To="Red" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Ellipse Name="icon"
                                 Height="24"
                                 Width="24"
                                 Opacity="1"
                                 Stretch="Uniform"
                                 VerticalAlignment="Center"
                                 Cursor="Hand"
                                 Fill="{TemplateBinding Background}" />
                        <Ellipse Name="iconDisable"
                                 Height="24"
                                 Width="24"
                                 Opacity="0"
                                 Stretch="Uniform"
                                 VerticalAlignment="Center"
                                 Cursor="Hand"
                                 Fill="#3D727272" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

代码的其他部分与您在问题帖子中写的相同。

答案 2 :(得分:0)

我使用 IsHitTestVisible 而不是 IsEnabled 。 以下是我解决问题的方法:

<ToggleButton x:Name="ToggleLock"
        IsChecked="{Binding OptionLocked}"
        Content="Lock"
        Width="100"
        Margin="20 10 0 10"
        VerticalAlignment="Top"
        Height="30" />
<ToggleButton x:Name="toggleButton"
        IsChecked="{Binding EllipseChecked}"
        Style="{StaticResource EllipseToggleButton}"
        IsHitTestVisible ="{Binding OptionLocked, Converter={StaticResource InvertBoolConv}}"/>

我有另一个问题。当ToggleLock打开时,我无法将背景颜色设置为灰色。至少它正在工作。如果几天内没有更多的答案,我会接受它。< / p>

答案 3 :(得分:0)

我想说谢谢Petter Hesselberg和TheSETJ。
最后我修复了它。这是一个新的ControlTemplate:

<ControlTemplate  TargetType="{x:Type ToggleButton}">
    <Grid>
        <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal" />
        <VisualState x:Name="Disabled" />
        </VisualStateGroup>
        <VisualStateGroup x:Name="CheckedStates">
        <VisualState x:Name="Checked">
        <Storyboard>
        <ColorAnimation x:Name="IconCheckedColorAni"
            Storyboard.TargetName="icon"
            Duration="0"
            Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)" />
        </Storyboard>
        </VisualState>
        <VisualState x:Name="Unchecked" />
        </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
            <Ellipse Name="icon"
            Height="24"
            Width="24"
            Stretch="Uniform"
            VerticalAlignment="Center"
            Cursor="Hand"
            Fill="{TemplateBinding Background}"
            Visibility="Visible" />
            <Ellipse Name="iconDisable"
            Height="24"
            Width="24"
            Stretch="Uniform"
            VerticalAlignment="Center"
            Cursor="Hand"
            IsHitTestVisible="{TemplateBinding IsHitTestVisible}"
            Fill="3D727272"
            Visibility="Collapsed" />
    </Grid>
    <ControlTemplate.Triggers>
    <Trigger Property="IsHitTestVisible">
        <Trigger.Value>
            <sys:Boolean>False</sys:Boolean>
        </Trigger.Value>
        <Setter TargetName="iconDisable"
            Property="Visibility"
            Value="Visible" />
            <Setter TargetName="icon"
            Property="Visibility"
            Value="Collapsed" />
        </Trigger>
        <Trigger Property="IsHitTestVisible">
            <Trigger.Value>
                <sys:Boolean>True</sys:Boolean>
            </Trigger.Value>
             <Setter TargetName="iconDisable"
                Property="Visibility"
                Value="Collapsed" />
                <Setter TargetName="icon"
                Property="Visibility"
                Value="Visible" />
        </Trigger>
        </ControlTemplate.Triggers>
</ControlTemplate>

MainWindow.xaml

<ToggleButton x:Name="ToggleLock"
        IsChecked="{Binding OptionLocked}"
        Content="Lock"
        Width="100"
        Margin="20 10 0 10"
        VerticalAlignment="Top"
        Height="30" />
<ToggleButton x:Name="toggleButton"
        IsChecked="{Binding EllipseChecked}"
        Style="{StaticResource EllipseToggleButton}"
        IsHitTestVisible ="{Binding OptionLocked, Converter={StaticResource InvertBoolConv}}"/>