1

我正在开发一个 Windows Phone 8 应用程序,并且我正在尝试创建一个用户控件,该控件在被选中时会改变其自身的大小。Selected/NotSelected 之间的更改是使用 VisualStateManager 完成的。为了保持下面的例子简单,我跳过这个并直接点击 UserControl。

问题是,我找不到任何方法来使用 Storyboard 更改 UserControl 的大小,因为我不知道如何在 Storyboard.TargetName 属性中引用 UserControl 本身:

<UserControl 
    x:Class="Namespace.MyUserControl"
    ...
    Tap="UserControl_Tap">

    <UserControl.Resources>
        <Storyboard x:Key="Expand">
            <DoubleAnimation To="400" Storyboard.TargetName="????" Storyboard.TargetProperty="Width">
                <DoubleAnimation.EasingFunction>
                    <CubicEase EasingMode="EaseInOut"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>

        <Storyboard x:Key="Collaps">
            ...
        </Storyboard>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <Rectangle x:Name="TestRect" Fill="Red" Width="10" Height="10"/>
    </Grid>
</UserControl>

private void UserControl_Tap(object sender, System.Windows.Input.GestureEventArgs e) {
    if (Width < 400) {
        Storyboard storyBoard = (Storyboard)this.Resources["Expand"];
        storyBoard.Begin();

        Width = 400;
        Height = 400;
    } else {
        Storyboard storyBoard = (Storyboard)this.Resources["Collaps"];
        storyBoard.Begin();

        Width = 200;
        Height = 200;
    }
}

故事板需要指定Storyboard.TargetName。应该用什么代替???引用 UserControl 本身?使用“ this ”不起作用并引发 InvalidOperationException“无法解析 TargetName this”。使用“ Namespace.MyUserControl ”时也会发生同样的情况。

使用“ LayoutRoot ”作为 TargetName 不会引发任何异常,但它也不起作用:没有任何反应。

对 UserControl 中的任何子控件进行动画处理(例如,使用 Storyboard.TargetName=TestRect" 的 TestRect )都可以正常工作。也可以直接设置 Width 和 Height 而无需任何 storyboard 工作没有任何问题。

知道如何解决这个问题吗?

4

2 回答 2

1

好的,这只是一个想法,但请您尝试一下。

当目标事件发生时,将动画从控件转换为变量,这是什么意思:

private void SomeEventOccured(object sender, RoutedEventArgs e)
 {
   var sb = _customUserControl.Expand;
   sb.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(CustomUserControl.WidthProperty));
   sb.SetValue(Storyboard.TargetNameProperty, _customUserControl.Name);
   sb.Begin();
 }

或者您可以将动画设置为Application.Resources

Storyboard sb = (Application.Current as App).Resources["Expand"] as Storyboard;

然后设置TargetNamePropertyand TargetPropertyProperty;

PS 我已经用我的 CustomUserControl 尝试过,TargetProperty 是不透明度。我希望这可以帮助你MSDNstackoverflow 问题

于 2013-11-04T16:09:43.560 回答
1

问题是,我不知道“UserControl”中的 Storybard 如何引用控件本身。据我所知,答案很简单: UserControl 中的任何元素都将以其名称为目标,因此只需给 UserControl 一个名称,它也可以作为目标:

<UserControl 
    x:Class="Namespace.MyUserControl"
    x:Name="_this"      <-- NAME GIVEN HERE CAN BE USED AS TAGETNAME FOR STORYBOARD
    ...
    Tap="UserControl_Tap">

    <UserControl.Resources>
        <Storyboard x:Key="Expand">
            <DoubleAnimation To="400" Storyboard.TargetName="_this" Storyboard.TargetProperty="Width">
                <DoubleAnimation.EasingFunction>
                    <CubicEase EasingMode="EaseInOut"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>

        <Storyboard x:Key="Collaps">
            ...
        </Storyboard>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot">
        <Rectangle x:Name="TestRect" Fill="Red" Width="10" Height="10"/>
    </Grid>
</UserControl> 

编辑于 2013 年 11 月 15 日

使用此解决方案时要小心。我在 PhonePage 上使用它来让它引用它,并在此页面上放置一个使用相同解决方案的 UserControl。因此,页面和 UserControl 都带有 x:Name=_this

应用程序有时会因System.InvalidCastException而崩溃,说“MyPageType”无法转换为“MyUserControlType”。我花了一段时间才弄清楚是什么导致了这个问题。元素不应共享相同的 x:Name。

使用 x:Name=thisMyPage 和 x:Name=thisMyControl 解决了这个问题。

于 2013-11-06T06:37:56.313 回答