在Silverlight故事板中缩小面板

4

我希望能够在按钮点击时缩小一个项目的宽度。

目前我有两个对象,当你点击objectA上的按钮时,会启动一个故事板来绕x轴旋转并折叠它。然后通过设置visibility属性为visible展示objectB,并将其旋转到视图中。

我想要添加的只是在故事板运行时将objectA和objectB的宽度设置小一些,然后在故事板结束时将其恢复到正常宽度。

我试过设置Thickness属性,但是编译时出现了只读错误。

<ObjectAnimationUsingKeyFrames
            BeginTime="00:00:00"
            Storyboard.TargetName="objectA"
            Storyboard.TargetProperty="(UIElement.Margin)">
      <DiscreteObjectKeyFrame KeyTime="00:00:00">
         <DiscreteObjectKeyFrame.Value>
            <Thickness Left="10" Right="10"/>
         </DiscreteObjectKeyFrame.Value>
      </DiscreteObjectKeyFrame>
   </ObjectAnimationUsingKeyFrames>

我现在有一个简单的布局...

这是我的UI XAML:

<StackPanel>
   <Border x:Name="objectA" BorderBrush="Blue" BorderThickness="1" Height="100" Width="100">
      <StackPanel>
         <TextBox Margin="10"></TextBox>
         <Button Width="50" x:Name="btn1" Content="Flip" Click="btn1_Click"/>
      </StackPanel>
    <Border.Projection>
      <PlaneProjection RotationX="0"></PlaneProjection>
    </Border.Projection>
  </Border>

  <Border Visibility="Collapsed" x:Name="objectB" BorderBrush="Red" BorderThickness="1" Height="100" Width="100">
     <StackPanel>
        <TextBox Margin="10"></TextBox>
        <Button Width="50" x:Name="btn2"  Content="Flip" Click="btn2_Click"/>
     </StackPanel>
     <Border.Projection>
        <PlaneProjection RotationX="90"></PlaneProjection>
     </Border.Projection>
  </Border>

这里是故事板...
 <Storyboard x:Name="Storyboardtest">
            <DoubleAnimation BeginTime="00:00:00"
              Storyboard.TargetName="objectA"
              Storyboard.TargetProperty="(UIElement.Projection).(RotationX)"

              From="0" To="-90">
            </DoubleAnimation>
            <ObjectAnimationUsingKeyFrames
                BeginTime="00:00:01"
                Storyboard.TargetName="objectA"
                Storyboard.TargetProperty="(UIElement.Visibility)">

                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Collapsed</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <ObjectAnimationUsingKeyFrames
                BeginTime="00:00:01"
                Storyboard.TargetName="objectB"
                Storyboard.TargetProperty="(UIElement.Visibility)">

                <DiscreteObjectKeyFrame KeyTime="00:00:00">
                    <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>

            </ObjectAnimationUsingKeyFrames>

            <DoubleAnimation BeginTime="00:00:01"
              Storyboard.TargetName="objectB"
              Storyboard.TargetProperty="(UIElement.Projection).(RotationX)"

              From="90" To="0">
            </DoubleAnimation>

        </Storyboard>

抱歉,您想更改控件实际占用的大小还是仅通过缩放来缩小控件宽度(例如使用缩放)?谢谢。 - iCollect.it Ltd
2个回答

5
如果只是想影响视觉宽度,可以在故事板中添加以下内容。它会使控件在翻转时呈现出向远处移动和向近处移动的外观效果:
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="objectA">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.5"/>
    </DoubleAnimationUsingKeyFrames>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="objectB">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.5"/>
        <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
    </DoubleAnimationUsingKeyFrames>

您还需要添加以下内容,因为我使用Expression Blend添加动画,它会自动添加任何所需的元素:

    <Border x:Name="objectA" BorderBrush="Blue" BorderThickness="1" Height="100" Width="100" RenderTransformOrigin="0.5,0.5">
        <Border.RenderTransform>
            <CompositeTransform/>
        </Border.RenderTransform>

[Snip]

    <Border Visibility="Collapsed" x:Name="objectB" BorderBrush="Red" BorderThickness="1" Height="100" Width="100" RenderTransformOrigin="0.5,0.5">
        <Border.RenderTransform>
            <CompositeTransform/>
        </Border.RenderTransform>

当我把你的代码放入我的示例中时,出现了以下错误:无法解析指定对象上的目标属性 (UIElement.RenderTransform).(CompositeTransform.ScaleX)。 - Gabe
你会注意到在我添加的缺失的XAML片段中,它们在两个边框上都有RenderTransformOrigin="0.5,0.5"。这意味着缩放将发生在中心而不是默认位置。抱歉我遗漏了一些细节。 - iCollect.it Ltd

0
问题在于Width和Margin属性都不是DependencyProperties,因此它们无法进行动画处理。解决此问题的一种方法是在用户控件的代码后台中添加一些自定义的DependencyProperties,这些DependencyProperties可以连接到故事板并进而操作对象的实际属性。
举个例子,您可以将此DependencyProperty添加到您的用户控件中,它基本上允许设置对象A的Width属性:
public static readonly DependencyProperty ObjectWidthProperty = DependencyProperty.Register(
    "ObjectWidth",
    typeof(double),
    typeof(MainPage),
    new PropertyMetadata(50.0, new PropertyChangedCallback(OnObjectWidthChanged)));

public double ObjectWidth
{
    get { return (double)GetValue(ObjectWidthProperty); }
    set { SetValue(ObjectWidthProperty, value); }
}

private static void OnObjectWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((MainPage)d).OnObjectWidthChanged(e);
}

private void OnObjectWidthChanged(DependencyPropertyChangedEventArgs e)
{
    this.objectA.Width = this.ObjectWidth;
}

然后,您可以将以下内容添加到您的故事板中,它将使对象A的宽度从50像素减少到0:

<DoubleAnimation BeginTime="00:00:00"
                 Storyboard.TargetName="MyControl"
                 Storyboard.TargetProperty="ObjectWidth"
                 From="50" To="0"/>

这也要求您将 x:Name="MyControl" 添加到顶级 UserControl 中。 这有点 hacky,但它可以使不是 DependencyPropertys 的一些基础元素的属性动画化。

虽然这个方法可行,但我不想缩小整个用户控件...不过或许可以把它作为起点 :) - Gabe
这并不会真正缩小整个用户控件,只是缩小了objectA。DependencyProperty仅在用户控件上公开,以便操作objectA的宽度,因为故事板无法直接更改objectA的Width属性。 - Dan Auclair

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接