我对动画绑定属性有一个简单的问题。这是一个简单的例子来说明:
ViewModel:
public class ViewModel
{
private double myProperty;
public double MyProperty
{
get { return myProperty; }
set { myProperty = value; /* Break point here */ }
}
public ViewModel()
{
MyProperty = 20;
}
}
MyControl:
public class MyControl : Button
{
protected override void OnClick()
{
base.OnClick();
Height = ActualHeight + 20;
}
}
MyAnimatedControl:
public class MyAnimatedControl : Button
{
protected override void OnClick()
{
base.OnClick();
DoubleAnimation a = new DoubleAnimation(ActualHeight + 20, new Duration(TimeSpan.FromMilliseconds(500)));
this.BeginAnimation(HeightProperty, a);
}
}
主窗口:
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new ViewModel();
InitializeComponent();
}
}
<Grid>
<StackPanel>
<local:MyAnimatedControl Height="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="Animated"/>
<local:MyControl Height="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="Normal 1"/>
<local:MyControl Height="{Binding MyProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="Normal 2"/>
</StackPanel>
</Grid>
我有两个从Button继承的控件(MyControl和MyAnimatedControl),它们的Height属性绑定(两种方式)到ViewModel中的MyProperty属性。
单击控件时,它们将增大其Height属性。MyControl为它分配一个新值,而MyAnimatedControl为它设置动画。
问题:
当我单击MyControl之一时,绑定正常工作,所有控件的高度都已更新,断点在ViewModel中起作用。但是,当我单击MyAnimatedControl时,绑定似乎不再起作用:它单独增长,并且绑定不再起作用,而两个常规控件仍然一起增长。它不再与其他控件共享相同的高度。
有没有一种方法可以对动画依赖项属性进行操作绑定,这将在整个动画过程中更新ViewModel?我读了这篇文章,但没有回答。
谢谢。
问题似乎在于,动画属性同时是绑定的来源。为了解决这个问题,您可以创建另一个height属性(例如MyHeight
),只要控件的高度发生变化,该属性就会更新,并用作OneWayToSource
绑定的目标。
public class MyAnimatedControl : Button
{
public static readonly DependencyProperty MyHeightProperty =
DependencyProperty.Register(
"MyHeight", typeof(double), typeof(MyAnimatedControl));
public double MyHeight
{
get { return (double)GetValue(MyHeightProperty); }
set { SetValue(MyHeightProperty, value); }
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
MyHeight = sizeInfo.NewSize.Height;
}
}
绑定:
<local:MyAnimatedControl ...
MyHeight="{Binding MyProperty, Mode=OneWayToSource}"
Height="{Binding MyProperty, Mode=OneWay}"/>
为了更新其他绑定目标,您还需要INotifyPropertyChanged
在视图模型中实现接口:
public class ViewModel : INotifyPropertyChanged
{
private double myProperty = 30;
public double MyProperty
{
get { return myProperty; }
set
{
myProperty = value;
RaisePropertyChanged("MyProperty");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
最后,正如Rohit Vats在他的回答中所写,您将需要删除Completed事件处理程序内Height属性上的动画保留:
protected override void OnClick()
{
base.OnClick();
DoubleAnimation a = new DoubleAnimation(ActualHeight + 20,
new Duration(TimeSpan.FromMilliseconds(500)));
a.Completed += (s, e) =>
{
BeginAnimation(Button.HeightProperty, null); // Remove animation.
SetCurrentValue(Button.HeightProperty, ActualHeight); // Set value.
};
this.BeginAnimation(Button.HeightProperty, a);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句