Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#/WPF在滥发';切换';_C#_Wpf_Animation_Storyboard - Fatal编程技术网

C#/WPF在滥发';切换';

C#/WPF在滥发';切换';,c#,wpf,animation,storyboard,C#,Wpf,Animation,Storyboard,基本上我有这个动画,当你点击按钮时,它会切换网格,显示或隐藏第二列(包含按钮2)。。。我的问题是,当您单击按钮时,动画将排队,因此它需要在执行第二个动画之前完成第一个动画。我唯一的解决办法是在动画处于活动状态时禁用按钮,然后在动画完成后重新启用它们。但我试图找到一种方法,使活动动画以某种方式中断,并使用网格的当前宽度来开始第二个动画 private void Window_Loaded(object sender, RoutedEventArgs e) { _toggle = false

基本上我有这个动画,当你点击按钮时,它会切换网格,显示或隐藏第二列(包含按钮2)。。。我的问题是,当您单击按钮时,动画将排队,因此它需要在执行第二个动画之前完成第一个动画。我唯一的解决办法是在动画处于活动状态时禁用按钮,然后在动画完成后重新启用它们。但我试图找到一种方法,使活动动画以某种方式中断,并使用网格的当前宽度来开始第二个动画

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _toggle = false;
    GridBodyWidthOne = new GridLength(1, GridUnitType.Star);
    GridBodyWidthZero = new GridLength(0, GridUnitType.Star);
    GridBody0Width = GridBodyWidthOne;
    GridBody1Width = GridBodyWidthZero;

    storyboard = this.FindResource("expandBody0") as Storyboard;
    storyboard.FillBehavior = FillBehavior.Stop;
    storyboard.Completed += (object o, EventArgs ea) => {
        GridBody0.Width = GridBodyWidthOne;
        GridBody1.Width = GridBodyWidthZero;
        GridBody0.BeginAnimation(ColumnDefinition.WidthProperty, null);
        GridBody1.BeginAnimation(ColumnDefinition.WidthProperty, null);
        GridSplitter0.IsEnabled = false;};

    storyboard = this.FindResource("retractBody0") as Storyboard;
    storyboard.FillBehavior = FillBehavior.Stop;
    storyboard.Completed += (object o, EventArgs ea) => {
        GridBody0.Width = GridBodyWidthOne;
        GridBody1.Width = GridBodyWidthOne;
        GridBody0.BeginAnimation(ColumnDefinition.WidthProperty, null);
        GridBody1.BeginAnimation(ColumnDefinition.WidthProperty, null);
        GridSplitter0.IsEnabled = true;};
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    ToggleMainBody1();
}

private void ToggleMainBody1()
{
    double maxWidth = GridBody0.ActualWidth + GridBody1.ActualWidth;
    double width0 = GridBody0.ActualWidth / maxWidth;
    double width1 = GridBody1.ActualWidth / maxWidth;
    GridBody0Width = new GridLength(width0, GridUnitType.Star);
    GridBody1Width = new GridLength(width1, GridUnitType.Star);

    if (!_toggle)
        RevealMainBody1();
    else
        HideMainBody1();

    _toggle = !_toggle;
}

private void HideMainBody1()
{
    //storyboard = this.FindResource("retractBody0") as Storyboard;
    //storyboard.Stop(this);
    storyboard = this.FindResource("expandBody0") as Storyboard;
    storyboard.Begin(this);
}

private void RevealMainBody1()
{
    //storyboard = this.FindResource("expandBody0") as Storyboard;
    //storyboard.Stop(this);
    storyboard = this.FindResource("retractBody0") as Storyboard;
    storyboard.Begin(this);
}
至于为什么我将FillBehavior设置为“Stop”,如果GridSplitter设置为“HoldEnd”,我会遇到一个问题“HoldEnd”实际上工作得很好,但当我通过GridSplitter调整它时就不行了。因此,基本上,当您双击切换按钮(或在没有第一个动画完成的情况下触发切换两次)时,问题就会出现



我准备了一个我认为可能对您有帮助的示例项目: 在本例中,我使用动画将按钮从最小宽度调整为最大宽度。要启动动画或反向运行动画,只需单击按钮

<Grid x:Name="rootGrid">
  <Button x:Name="button" MinWidth="40" Width="40" Content="Expand" 
          local:MainWindow.AnimationDuration="0:0:2"  HorizontalAlignment="Left" Click="button_Click" >

     <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
           <BeginStoryboard>
              <Storyboard>
                 <DoubleAnimation
                            Storyboard.TargetName="button"
                            Storyboard.TargetProperty="Width"
                            From="{Binding ActualWidth,  ElementName=button}" 
                            Duration="{Binding Path=(local:MainWindow.AnimationDuration), ElementName=button}">
                    <DoubleAnimation.To>
                       <MultiBinding Converter="{StaticResource ToWidthConverter}">
                          <Binding  ElementName="button" Path="Tag" />
                          <Binding  ElementName="button" Path="MinWidth" />
                          <Binding  ElementName="rootGrid" Path="ActualWidth" />
                       </MultiBinding>
                    </DoubleAnimation.To>
                 </DoubleAnimation>     
              </Storyboard>
           </BeginStoryboard>
        </EventTrigger>
     </Button.Triggers>
  </Button>
</Grid>

你能把完整的XAML作为文本(而不是屏幕截图)吗?用XAML更新后,如果需要,我还可以更新后面的代码以包含所有其他内容(我只是尝试将代码精简到我认为重要的部分,但我可能遗漏了一些东西)。。。谢谢显然,我的数学不正确(忘记了交换“to”和“from”),但是看到你的答案,我想研究一下,并把它加入我的武库,谢谢!
<Grid x:Name="rootGrid">
  <Button x:Name="button" MinWidth="40" Width="40" Content="Expand" 
          local:MainWindow.AnimationDuration="0:0:2"  HorizontalAlignment="Left" Click="button_Click" >

     <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
           <BeginStoryboard>
              <Storyboard>
                 <DoubleAnimation
                            Storyboard.TargetName="button"
                            Storyboard.TargetProperty="Width"
                            From="{Binding ActualWidth,  ElementName=button}" 
                            Duration="{Binding Path=(local:MainWindow.AnimationDuration), ElementName=button}">
                    <DoubleAnimation.To>
                       <MultiBinding Converter="{StaticResource ToWidthConverter}">
                          <Binding  ElementName="button" Path="Tag" />
                          <Binding  ElementName="button" Path="MinWidth" />
                          <Binding  ElementName="rootGrid" Path="ActualWidth" />
                       </MultiBinding>
                    </DoubleAnimation.To>
                 </DoubleAnimation>     
              </Storyboard>
           </BeginStoryboard>
        </EventTrigger>
     </Button.Triggers>
  </Button>
</Grid>
    private void button_Click(object sender, RoutedEventArgs e) {
   double currentPosition = (button.ActualWidth - button.MinWidth) / (rootGrid.ActualWidth - button.MinWidth);
   if (button.Tag is bool && (bool)button.Tag)
      button.Tag = false;
   else {
      currentPosition = 1 - currentPosition;
      button.Tag = true;
   }
   SetAnimationDuration(button, new Duration(TimeSpan.FromSeconds(5 * currentPosition)));
}