我正在尝试创建一个可以调整大小和折叠/展开的用户控件(带动画)。当我播放折叠/展开动画时,调整大小停止工作。
完整的测试应用程序可在此处找到:App
编辑:这是所要求的相关代码
MyControl.xaml:
<UserControl x:Class="WpfApp1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid Background="#FF935E5E">
<Thumb Width="8"
HorizontalAlignment="Right"
Margin="0,0,-4,0"
DragDelta="Thumb_DragDelta"
Cursor="SizeWE"/>
</Grid>
MyControl.xaml.cs:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MyControl.xaml
/// </summary>
public partial class MyControl : UserControl
{
public bool IsOpen
{
get { return (bool)GetValue(IsOpenProperty); }
set { SetValue(IsOpenProperty, value); }
}
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register("IsOpen", typeof(bool), typeof(MyControl), new PropertyMetadata(true, OnIsOpenChanged));
private static void OnIsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyControl control = d as MyControl;
control.PlayAnimation();
}
public double OpenWidth
{
get { return (double)GetValue(OpenWidthProperty); }
set { SetValue(OpenWidthProperty, value); }
}
public static readonly DependencyProperty OpenWidthProperty =
DependencyProperty.Register("OpenWidth", typeof(double), typeof(MyControl), new PropertyMetadata(300d, OnOpenWidthChanged));
private static void OnOpenWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MyControl control = d as MyControl;
if (control.IsOpen)
control.Width = control.OpenWidth;
}
public MyControl()
{
InitializeComponent();
if (IsOpen)
Width = OpenWidth;
}
private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
OpenWidth += e.HorizontalChange;
}
private void PlayAnimation()
{
DoubleAnimation sizeAnimation = new DoubleAnimation(IsOpen ? OpenWidth : 0, TimeSpan.FromMilliseconds(250));
sizeAnimation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseInOut };
BeginAnimation(WidthProperty, sizeAnimation);
}
}
}
MainWindow.xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="700">
<DockPanel>
<local:MyControl IsOpen="{Binding ControlIsOpen}"
OpenWidth="{Binding ControlOpenWidth}"/>
<Grid Background="Green">
<Button Width="100"
Height="20"
Content="Test Animation"
Click="Button_Click"/>
</Grid>
</DockPanel>
MainWindow.xaml.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
#endregion INotifyPropertyChanged
private bool _ControlIsOpen = true;
public bool ControlIsOpen
{
get => _ControlIsOpen;
set
{
_ControlIsOpen = value;
OnPropertyChanged();
}
}
private double _ControlOpenWidth = 300d;
public double ControlOpenWidth
{
get => _ControlOpenWidth;
set
{
_ControlOpenWidth = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
ControlIsOpen = !ControlIsOpen;
}
}
}
感谢您的帮助:)
答案 0 :(得分:1)
动画实际上永远不会停止你应该指定FillBehavior停止。在这种情况下,annimation将在达到最终值后停止更新属性。
private void PlayAnimation()
{
DoubleAnimation sizeAnimation = new DoubleAnimation(IsOpen ? OpenWidth : 0, TimeSpan.FromMilliseconds(250));
sizeAnimation.FillBehavior = FillBehavior.Stop;
sizeAnimation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseInOut };
sizeAnimation.Completed += OnAnimationCompleted;
BeginAnimation(WidthProperty, sizeAnimation);
}
private void OnAnimationCompleted(object sender, EventArgs e)
{
Width = IsOpen ? OpenWidth : 0;
}
默认值为HoldEnd。故事板将修改宽度,直到它没有明确停止。
答案 1 :(得分:0)
非常感谢德米特里的想法,我已经能够解决它,通过设置填充行为来停止并强制宽度为0或开放宽度:
private void PlayAnimation()
{
DoubleAnimation sizeAnimation = new DoubleAnimation(IsOpen ? OpenWidth : 0, TimeSpan.FromMilliseconds(250));
sizeAnimation.EasingFunction = new CircleEase() { EasingMode = EasingMode.EaseInOut };
sizeAnimation.FillBehavior = FillBehavior.Stop;
sizeAnimation.Completed += (s, e) => Width = (IsOpen ? OpenWidth : 0);
BeginAnimation(WidthProperty, sizeAnimation);
}
全部谢谢:)