【问题标题】:How can a UserControl change its own size using a Storyboard?UserControl 如何使用 Storyboard 更改自己的大小?
【发布时间】:2013-11-14 23:52:50
【问题描述】:

我正在开发一个 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 需要指定 Storyboard.TargetName。应该使用什么来代替 ???? 来引用 UserControl 本身?使用“this”不起作用并引发 InvalidOperationException“无法解析 TargetName this”。使用“Namespace.MyUserControl”时也会发生同样的情况。

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

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

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

【问题讨论】:

  • 为什么不在目标页面中创建故事板,这样用户控件是由其属性定义的
  • UserControl 应该在许多不同的页面上使用,并且行为应该始终相同。执行一次行为(在 UserControl 内)而不是在使用 UserControl 的每个页面上执行此操作不是更好吗?

标签: c# visual-studio windows-phone-8 user-controls storyboard


【解决方案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;

然后设置TargetNamePropertyTargetPropertyProperty

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

【讨论】:

  • 非常感谢您的回答!我认为您的解决方案可能有效。同时,我找到了一个更简单的解决方案。我将其添加为答案,以防万一其他人有同样的问题
【解决方案2】:

问题是,我不知道“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 解决了这个问题。

【讨论】:

    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 2011-03-23
    • 2015-01-01
    • 2016-02-28
    • 2014-12-23
    • 2019-03-15
    • 1970-01-01
    • 2016-04-25
    相关资源
    最近更新 更多