在我的应用中,我有Left Grid
和Right Grid
。最初,Left Grid
完全展开(GridLength = 7*
)而Right Grid
不可见(Width = 0*
)。
如果点击Button
中的LeftGrid
并且Right Grid
未展开,则Right Grid
应扩展为Width
3*
}。
如果Right Grid
已展开并且Button
中的LeftGrid
被连续点击两次,则RightGrid
应缩减回Width
{ {1}}。
这些扩展/收缩应为0*
。
点击Animated
时,必须发生三件事。
1)所选Button
的{{1}}应存储在id
的{{1}}中。
2)Button
将设置到的Property
存储在ViewModel
的{{1}}中。这个Width
负责连续两次点击案例。
3)最后,RightGrid
应该运行。
我遇到了一些问题:
1)如何将两个Property
绑定到一个ViewModel
?
Command
这是不允许的。
我一直在看这篇文章(http://www.codeproject.com/Articles/25808/Aggregating-WPF-Commands-with-CommandGroup)。
但是,我不确定这是否对我有用,因为我在Animation
中定义了Commands
。
2)我正在使用自定义Button
动画类,因为我需要<Button DockPanel.Dock="Top"
Command="{Binding DataContext.SetSelectedItemCommand,
RelativeSource={RelativeSource
AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding id}"
Command="{Binding ElementName=root, Path=DataContext.ChangeRightGridWidthCommand}"
>
用于Commands
。
ViewModel
我打算在GridLength
:
*
我应该将上述Widths
代码放在:
public class GridLengthAnimation : AnimationTimeline
{
public static readonly DependencyProperty ToProperty =
DependencyProperty.Register(
"To", typeof(GridLength), typeof(GridLengthAnimation));
public GridLength To
{
get { return (GridLength)GetValue(ToProperty); }
set { SetValue(ToProperty, value); }
}
public override Type TargetPropertyType
{
get { return typeof(GridLength); }
}
protected override Freezable CreateInstanceCore()
{
return new GridLengthAnimation();
}
public override object GetCurrentValue(
object defaultOriginValue, object defaultDestinationValue,
AnimationClock animationClock)
{
return new GridLength(To.Value,
GridUnitType.Star);
}
}
如果是,我的XAML
或<proj:GridLengthAnimation
Storyboard.TargetName="rightGrid"
Storyboard.TargetProperty="Width"
To="RightGridWidth" Duration="0:0:2" />
<Grid.ColumnDefinitions>
<ColumnDefinition Name="leftGrid" Width="7*"/>
<ColumnDefinition Name="rightGrid" Width="{Binding RightGridWidth}"/>
</Grid.ColumnDefinitions>
会先运行吗?我需要先运行XAML
,因为只有在 <EventTrigger RoutedEvent="Button.Click">
运行时才能正确设置Commands
值。
我很困惑如何将所有这些放在一起。
非常感谢任何帮助/建议!!
答案 0 :(得分:0)
使用已有的内容快速而肮脏,即运行动画的EventTrigger。
将RightGridWidth
属性(包含更改通知)添加到您的视图模型中:
public GridLength RightGridWidth
{
get { return rightGridWidth; }
set
{
rightGridWidth = value;
OnPropertyChanged("RightGridWidth");
}
}
在SetSelectedItemCommand
的执行处理程序中切换属性值:
if (RightGridWidth.Value == 0d)
{
RightGridWidth = new GridLength(3d, GridUnitType.Star);
}
else
{
RightGridWidth = new GridLength(0d, GridUnitType.Star);
}
在Click
EventTrigger:
<Button Content="Click" Command="{Binding SetSelectedItemCommand}">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<local:GridLengthAnimation
Storyboard.Target="{Binding ElementName=col2}"
Storyboard.TargetProperty="Width"
Duration="0:0:1" To="{Binding RightGridWidth}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
最后,使用动画GetCurrentValue
的工作实现,该实现必须返回一个取决于CurrentProgress
的值:
public override object GetCurrentValue(
object defaultOriginValue, object defaultDestinationValue,
AnimationClock animationClock)
{
var from = (GridLength)defaultOriginValue;
if (from.GridUnitType != To.GridUnitType ||
!animationClock.CurrentProgress.HasValue)
{
return from;
}
var p = animationClock.CurrentProgress.Value;
return new GridLength(
(1d - p) * from.Value + p * To.Value,
from.GridUnitType);
}
完全不同的也许更好的方法是使用视觉状态。请参阅VisualStateManager。