我有一个ItemsControl,其中的项通过数据绑定添加到一个可观察的集合中。每个项都有一个定义其外观的数据模板。
我正在尝试弄清楚,当VisualStateManager将ItemsControl置于特定状态时,是否可以对ItemsControl中的每个项目应用/触发动画。
下面是一张图片-当items控件进入关闭状态时-我希望items控件中的项目缩小并隐藏文本,并使数字变为可见。是否可以使用VSM,或者我是否需要在创建每个项目时将动画附加到每个项目,然后在我希望它们更改视觉状态时手动将其踢开。
alt text http://www.edefine.com/images/misc/drawing1.jpg
发布于 2009-04-02 09:36:23
使用ObjectAnimationUsingKeyFrames可以做到这一点,但是这很难做到,这会让你抓狂,经常让你的visual studio崩溃,而且用简单的方法几乎不会给你带来什么好处。
简单的方法:
public class TestSwapContentControl : ContentControl
{
object StoredOriginalContent;
public object FullContent
{
get { return (object)GetValue(FullContentProperty); }
set { SetValue(FullContentProperty, value); }
}
// Using a DependencyProperty as the backing store for FullContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FullContentProperty =
DependencyProperty.Register(
"FullContent"
, typeof(object)
, typeof(TestSwapContentControl)
, null);
public void SwitchToFullContent()
{
if (FullContent != null)
{
StoredOriginalContent = Content;
Content = FullContent;
}
}
public void SwitchToNormalContent()
{
if(StoredOriginalContent != null)
{
Content = StoredOriginalContent;
}
}
}然后使用xaml:
<local:TestSwapContentControl x:Name="mySwitch">
<Rectangle Height="50" Width="100" Fill="Black" />
<local:TestSwapContentControl.FullContent>
<StackPanel>
<TextBlock>1</TextBlock>
<TextBlock>2</TextBlock>
<TextBlock>3</TextBlock>
<TextBlock>4</TextBlock>
<Rectangle Height="50" Width="100" Fill="Red" />
</StackPanel>
</local:TestSwapContentControl.FullContent>
</local:TestSwapContentControl> 页面中包含以下cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (myTempBool)
{
mySwitch.SwitchToFullContent();
myTempBool = false;
}
else
{
mySwitch.SwitchToNormalContent();
myTempBool = true;
}
}现在,如果你真的需要让其他开发人员完全扩展这个控件,你需要使用visualstatemenager,但这真的很难。如果您不知道如何通过generic.xaml设置可视化状态管理器和状态,这里有一个操作指南:
http://scorbs.com/2008/06/11/parts-states-model-with-visualstatemanager-part-1-of/
这是一个工作示例,但它并不完美,因为我似乎不能直接设置ContentPresenter的内容。
using System.Windows;
using System.Windows.Controls;
namespace SilverlightTestApplication
{
[TemplateVisualState(Name="Normal", GroupName="SizeStates")]
[TemplateVisualState(Name="Expanded", GroupName="SizeStates")]
public class TestVSMControl : ContentControl
{
public object SmallContent
{
get { return (object)GetValue(SmallContentProperty); }
set { SetValue(SmallContentProperty, value); }
}
// Using a DependencyProperty as the backing store for SmallContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SmallContentProperty =
DependencyProperty.Register("SmallContent", typeof(object), typeof(TestVSMControl), null);
public object LargeContent
{
get { return (object)GetValue(LargeContentProperty); }
set { SetValue(LargeContentProperty, value); }
}
// Using a DependencyProperty as the backing store for LargeContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LargeContentProperty =
DependencyProperty.Register("LargeContent", typeof(object), typeof(TestVSMControl), null);
public bool Pressed
{
get { return (bool)GetValue(PressedProperty); }
set { SetValue(PressedProperty, value); }
}
// Using a DependencyProperty as the backing store for Pressed. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PressedProperty =
DependencyProperty.Register("Pressed", typeof(bool), typeof(TestVSMControl),
new PropertyMetadata(new PropertyChangedCallback(PressedPropertyChanged)));
static void PressedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var me = sender as TestVSMControl;
me.ChangeState();
}
public TestVSMControl()
{
DefaultStyleKey = typeof(TestVSMControl);
}
void ChangeState()
{
GoToState(true);
}
private void GoToState(bool useTransitions)
{
if (Pressed)
{
VisualStateManager.GoToState(this, "Normal", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Expanded", useTransitions);
}
}
}
}在您的generic.xaml中(包括xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"):
<Style TargetType="local:TestVSMControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestVSMControl">
<StackPanel>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SizeStates">
<vsm:VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<StackPanel>
<TextBlock>Rararasputin</TextBlock>
<Button Content="{TemplateBinding SmallContent}" />
</StackPanel>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Expanded">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0" >
<DiscreteObjectKeyFrame.Value>
<StackPanel>
<TextBlock>Other one</TextBlock>
<Button Content="{TemplateBinding LargeContent}" />
</StackPanel>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="myContentPresenter" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>以及如何在页面中使用:
<local:TestVSMControl x:Name="myVSMControl" Height="200">
<local:TestVSMControl.SmallContent>
<Rectangle Height="50" Width="100" Fill="Red" />
</local:TestVSMControl.SmallContent>
<local:TestVSMControl.LargeContent>
<Rectangle Height="50" Width="100" Fill="Green" />
</local:TestVSMControl.LargeContent>
</local:TestVSMControl>
<Button Content="Swap" x:Name="VSMButton" Click="VSMButton_Click" />在您的页面中包含以下内容:
private void VSMButton_Click(object sender, RoutedEventArgs e)
{
myVSMControl.Pressed = !myVSMControl.Pressed;
}发布于 2009-03-29 02:05:38
如果您正在谈论Silverlight可视化状态管理器,恐怕这是不可能的。
VisualStates仅包含故事板对象,而故事板对象又包含动画。据我所知,您不能使用它更改模板。
我不确定WPF VisualStateManager的功能。
https://stackoverflow.com/questions/693960
复制相似问题