You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

绑定ToggleButton的IsChecked属性后触发InvalidOperationException:未找到Ellipse

问题

使用ToggleButton自定义样式后,将IsChecked属性绑定到ViewModel的IsAutostop属性时,程序崩溃并抛出System.InvalidOperationException,错误提示在System.Windows.Controls.ControlTemplate中未找到名为Ellipse的元素。

自定义样式代码

<Style TargetType="{x:Type ToggleButton}">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type ToggleButton}">
            <Viewbox>
               <Border x:Name="Border"
                  CornerRadius="10"
                  Background="#FFE2E2E2"
                  Width="40"
                  Height="20">
                  <Border.Effect>
                      <DropShadowEffect ShadowDepth="0.5"
                         Direction="0"
                         Opacity="0.3" />
                   </Border.Effect>
                   <Ellipse x:Name="Ellipse"
                      Fill="#FF909090"
                      Stretch="Uniform"
                      Margin="-8 -4"
                      Stroke="Gray"
                      StrokeThickness="0.2"
                      HorizontalAlignment="Stretch">
                   <Ellipse.Effect>
                      <DropShadowEffect BlurRadius="10"
                         ShadowDepth="1"
                         Opacity="0.3"
                         Direction="260" />
                   </Ellipse.Effect>
                </Ellipse>
             </Border>
          </Viewbox>
          <ControlTemplate.Triggers>
             <EventTrigger RoutedEvent="Checked">
                <BeginStoryboard>
                   <Storyboard>
                      <ColorAnimation Storyboard.TargetName="Ellipse"
                         Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                         To="#00facc"
                         Duration="0:0:0.05"
                         AccelerationRatio="0.7"
                         DecelerationRatio="0.3" />
                      <ThicknessAnimation Storyboard.TargetName="Ellipse"
                         Storyboard.TargetProperty="Margin"
                         To="20 -4 -8 -4"
                         Duration="0:0:0.15"
                         AccelerationRatio="0.7"
                         DecelerationRatio="0.3" />
                      </Storyboard>
                   </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="Unchecked">
                  <BeginStoryboard>
                    <Storyboard>
                      <ColorAnimation Storyboard.TargetName="Ellipse"
                        Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                        To="#00facc"
                        Duration="0:0:0.05"
                        AccelerationRatio="0.7"
                        DecelerationRatio="0.3" />
                     <ThicknessAnimation 
                        Storyboard.TargetName="Ellipse"                                                            
                        Storyboard.TargetProperty="Margin"
                        To="-8 -4"
                        Duration="0:0:0.15"
                        AccelerationRatio="0.7"
                        DecelerationRatio="0.3" />
                     </Storyboard>
                  </BeginStoryboard>
               </EventTrigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

使用方式

<ToggleButton Grid.Column="0"
   Grid.Row="2"
   IsChecked="{Binding IsAutostop}"/>

补充场景

通过任务栏图标的命令触发窗口打开:

WindowService代码

class WindowService
{
    public void OpenOptionsView(MainViewModel mvm)
    {
        OptionsView optionsView = new OptionsView { DataContext = mvm };
        optionsView.Show();
    }
}

MainViewModel关键代码

public ICommand OpenOptionsViewCommand { get; private set; }
public bool IsAutostop { get { return Settings.Default.Autostop; } set { Settings.Default.Autostop = value; Settings.Default.Save(); OnPropertyChanged(); } }

public MainViewModel() 
{
   OpenOptionsViewCommand = new RelayCommand(OpenOptionsView, param => true);
}

private void OpenOptionsView(object o)
{
   WindowService ws = new WindowService();
   ws.OpenOptionsView(this);
}

任务栏图标XAML

<tb:TaskbarIcon>
   <tb:TaskbarIcon.ContextMenu>
      <ContextMenu Background="#1e1e1e">
         <MenuItem Header="Programm öffnen"  
                   Foreground="White"
                   Command="{Binding OpenOptionsViewCommand}"/>
      </ContextMenu>
   </tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>

解决方案

1. 替换EventTrigger为PropertyTrigger

问题根源在于Checked/Unchecked事件可能在ControlTemplate内的Ellipse元素尚未完成初始化时就触发,导致动画找不到目标元素。改用监听IsChecked属性变化的Trigger可以避免这个问题,因为属性触发会等待模板元素加载完成后再执行:

修改ControlTemplate的Triggers部分:

<ControlTemplate.Triggers>
   <Trigger Property="IsChecked" Value="True">
      <Trigger.EnterActions>
         <BeginStoryboard>
            <Storyboard>
               <ColorAnimation Storyboard.TargetName="Ellipse"
                  Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                  To="#00facc"
                  Duration="0:0:0.05"
                  AccelerationRatio="0.7"
                  DecelerationRatio="0.3" />
               <ThicknessAnimation Storyboard.TargetName="Ellipse"
                  Storyboard.TargetProperty="Margin"
                  To="20 -4 -8 -4"
                  Duration="0:0:0.15"
                  AccelerationRatio="0.7"
                  DecelerationRatio="0.3" />
            </Storyboard>
         </BeginStoryboard>
      </Trigger.EnterActions>
      <Trigger.ExitActions>
         <BeginStoryboard>
            <Storyboard>
               <!-- 取消选中时恢复为原始灰色 -->
               <ColorAnimation Storyboard.TargetName="Ellipse"
                  Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"
                  To="#FF909090"
                  Duration="0:0:0.05"
                  AccelerationRatio="0.7"
                  DecelerationRatio="0.3" />
               <ThicknessAnimation 
                  Storyboard.TargetName="Ellipse"                                                            
                  Storyboard.TargetProperty="Margin"
                  To="-8 -4"
                  Duration="0:0:0.15"
                  AccelerationRatio="0.7"
                  DecelerationRatio="0.3" />
            </Storyboard>
         </BeginStoryboard>
      </Trigger.ExitActions>
   </Trigger>
</ControlTemplate.Triggers>

2. 修复动画颜色错误

原代码中Unchecked事件的ColorAnimation目标颜色错误设置为#00facc,取消选中时应该恢复为初始的灰色#FF909090,上述代码已修正该问题。

3. 延迟DataContext设置(可选)

如果问题仍然存在,可以在窗口Loaded事件触发后再设置DataContext,确保模板完全加载:

修改WindowService的代码:

public void OpenOptionsView(MainViewModel mvm)
{
    OptionsView optionsView = new OptionsView();
    optionsView.Loaded += (s, e) => 
    {
        optionsView.DataContext = mvm;
    };
    optionsView.Show();
}

内容的提问来源于stack exchange,提问作者Schulze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:16:36