1

我正在尝试为视觉刷中的许多形状设置动画,但是当我执行旋转时,形状“脉冲”。我假设随着形状的旋转,边界框会强制布局通过。但是,由于我使用的是 RenderTransform,我没想到这会触发布局更改。

这段代码说明了这个问题:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="200" Width="200">
<StackPanel>
    <Border BorderBrush="Red" BorderThickness="1"
            Height="100" Width="100">
        <Border.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard>
                    <Storyboard RepeatBehavior="Forever" >
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse"
                            Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
                            <LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
                <BeginStoryboard>
                    <Storyboard  RepeatBehavior="Forever" >
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
                            Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">                                             
                            <LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Border.Triggers>
        <Border.Background>
            <VisualBrush Stretch="Uniform">
                <VisualBrush.Visual>                      
                    <Canvas Width="20" Height="20">
                        <Ellipse x:Name="outer_Ellipse" 
                                 Stroke="Blue" StrokeThickness="1"   
                                 Width="20" Height="20" 
                                 RenderTransformOrigin="0.5,0.5">
                            <Ellipse.RenderTransform>
                                    <RotateTransform/>
                            </Ellipse.RenderTransform>
                        </Ellipse>
                        <Ellipse  x:Name="inner_Ellipse" 
                                  Stroke="Red" StrokeThickness="1"
                                  Width="18" Height="18" 
                                  Margin="1,1,0,0"
                                  RenderTransformOrigin="0.5,0.5">
                            <Ellipse.RenderTransform>
                                    <RotateTransform/>
                            </Ellipse.RenderTransform>
                        </Ellipse>
                    </Canvas>
                </VisualBrush.Visual>
            </VisualBrush>
        </Border.Background>
    </Border>
</StackPanel>

这是一个更复杂的应用程序的简单示例,我使用视觉画笔来装饰在 3d 中操作的 2d 平面。在我尝试为画笔设置动画之前,这一切都很好。我尝试了几种不同的方法,但似乎总是遇到这个布局问题。

任何建议表示赞赏。

谢谢

4

2 回答 2

2

我能够找到您的问题的原因。它与Stretch="Uniform"您的VisualBrush. 看起来框架正在计算您的 VisuaBrush.Visual 上的边界矩形,然后将其拉伸以适应Border.Background. 以下代码应说明该行为。我拿出你的 inner_Ellipse 并添加了一个 external_Rectangle ,它应该模拟被拉伸的边界矩形:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="200" Width="200">
    <StackPanel>
        <Border BorderBrush="Red" BorderThickness="1"
            Height="100" Width="100">
            <Border.Triggers>
                <EventTrigger RoutedEvent="FrameworkElement.Loaded">                
                    <BeginStoryboard>
                        <Storyboard  RepeatBehavior="Forever" >
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Rectangle"
                            Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
                                <LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                    <BeginStoryboard>
                        <Storyboard  RepeatBehavior="Forever" >
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
                            Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
                                <LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Border.Triggers>
            <Border.Background>
                <VisualBrush Stretch="Uniform">
                    <VisualBrush.Visual>
                        <Canvas Width="20" Height="20">
                            <Ellipse x:Name="outer_Ellipse" 
                                 Stroke="Blue" StrokeThickness="1"   
                                 Width="20" Height="20" 
                                 RenderTransformOrigin="0.5,0.5">
                                <Ellipse.RenderTransform>
                                    <RotateTransform/>
                                </Ellipse.RenderTransform>
                            </Ellipse>
                            <Rectangle x:Name="outer_Rectangle" 
                                 Stroke="Blue" StrokeThickness="1"   
                                 Width="20" Height="20" 
                                 RenderTransformOrigin="0.5,0.5">
                                <Rectangle.RenderTransform>
                                    <RotateTransform/>
                                </Rectangle.RenderTransform>
                            </Rectangle>
                        </Canvas>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Border.Background>
        </Border>
    </StackPanel>
</Window>

至于解决问题,我不确定。一种方法是Stretch="None"在您的 VisualBrush 上使用,但这似乎并不理想,因为它会由您来处理 VisualBrush.Visual 内容的大小。

于 2012-03-15T20:34:33.620 回答
0

经过大量的反复试验,我有了一个可行的解决方案。VisualBrush 的内容正确缩放并且不会导致边界框问题:

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    SizeToContent="WidthAndHeight" >
<StackPanel>
    <Border BorderBrush="Black" BorderThickness="1"
        Height="400" Width="400">
        <Border.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard>
                    <Storyboard RepeatBehavior="Forever" >
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse"
                        Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
                            <LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
                <BeginStoryboard>
                    <Storyboard  RepeatBehavior="Forever" >
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
                        Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
                            <LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Border.Triggers>

        <Border.Background>
            <VisualBrush Stretch="UniformToFill">
                <VisualBrush.Visual>
                    <Border BorderBrush="Transparent" BorderThickness="1"
                            Width="200" Height="200">
                        <StackPanel Width="200" Height="200">
                            <Canvas>
                                <Rectangle x:Name="outer_Ellipse" 
                                        Stroke="Blue" StrokeThickness="1"   
                                        Width="20" Height="200" 
                                           Canvas.Left="40"
                                        RenderTransformOrigin="0.5,0.5">
                                    <Rectangle.RenderTransform>
                                        <RotateTransform/>
                                    </Rectangle.RenderTransform>
                                </Rectangle>
                                <Ellipse x:Name="inner_Ellipse" 
                                         Stroke="Red" StrokeThickness="1"
                                         StrokeDashArray="2"
                                         Canvas.Top="30"
                                         Canvas.Left="20"
                                        Width="200" Height="200" 
                                        RenderTransformOrigin="0.5,0.5">
                                    <Ellipse.RenderTransform>
                                        <RotateTransform/>
                                    </Ellipse.RenderTransform>
                                </Ellipse>
                            </Canvas>
                        </StackPanel>
                    </Border>
                </VisualBrush.Visual>
            </VisualBrush>
        </Border.Background>
    </Border>
</StackPanel>
</Window>

“秘密”似乎将包含画笔内容的画布包裹在 StackPanel 中,并将其包裹在边框中。(Grid、DockPanel 和 WrapPanel 也可以代替 StackPanel)。

                        <Border BorderBrush="Transparent" BorderThickness="1"
                            Width="200" Height="200">
                        <StackPanel Width="200" Height="200">

Border 必须有一个 BorderBrush 集和一个 BorderThickness。此外,它们都必须具有明确的宽度和高度。在这里,我设置了适合内容的值,因此它可以正确缩放。

如果没有所有这 3 个组件,则会再次出现边界框问题。显然,容器的布局策略有所不同,但我不知道是什么或为什么。

根本不是一个令人满意的解决方案,如果有人能阐明这里发生的事情,我将不胜感激。

至少它在上面的演示和我的主应用程序中都有效,无论如何!

于 2012-03-16T20:32:34.320 回答