WPF中的RenderTransform导致意外布局更改
我试图在visualbrush中设置许多形状的动画,但当我执行旋转时,形状会“脉冲”。我假设当形状旋转时,边界框将强制进行布局传递。然而,由于我使用的是RenderTransform,我没想到会触发布局更改 此代码说明了问题:WPF中的RenderTransform导致意外布局更改,wpf,rotation,visualbrush,Wpf,Rotation,Visualbrush,我试图在visualbrush中设置许多形状的动画,但当我执行旋转时,形状会“脉冲”。我假设当形状旋转时,边界框将强制进行布局传递。然而,由于我使用的是RenderTransform,我没想到会触发布局更改 此代码说明了问题: <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http:
<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平面。这一切都很好,直到我尝试和动画画笔。我尝试过几种不同的方法,但似乎总是遇到这个布局问题
如有任何建议,我们将不胜感激
谢谢
Rob我找到了你问题的原因。它与
VisualBrush
上的Stretch=“Uniform”
属性设置有关。框架似乎正在计算visualAbrush.Visual上的一个边框,然后拉伸它以适应Border.Background
。下面的代码应该说明该行为。我取出了您的内部_椭圆,并添加了一个外部_矩形,该矩形应模拟正在拉伸的边界矩形:
<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>
至于解决这个问题,我不确定。一种方法是在你的VisualBrush上使用
Stretch=“None”
,但这似乎并不理想,因为你需要处理VisualBrush的大小。视觉内容。经过大量的尝试和错误,我有了一个有效的解决方案。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中,并将其包装在边框中。(网格、DockPanel和WrapPanel也将取代StackPanel)
边框必须具有边框笔刷集和边框厚度。此外,它们都必须具有明确的宽度和高度。在这里,我设置了适合内容的值,以便它能够正确缩放
如果没有这三个组件,边界框问题再次出现。很明显,集装箱的布局政策有一些不同,但我不知道是什么或为什么
这根本不是一个令人满意的解决方案,如果有人能告诉我这里发生了什么,我将不胜感激
至少它在上面的演示和我的主应用程序中都能工作,不管怎样,到目前为止
Rob是的,我知道关闭拉伸可以修复它,假设内部内容不大于视觉应用到的对象。你的例子可能更好地说明了这个问题。问题是我的画笔“内容”来自datatemplates,拉伸是正确的行为,这取决于被修饰控件的大小。基本上,我希望在这种情况下,如果视觉效果超出边界的边界框,那么它将“剪辑”在后面。谢谢
<Border BorderBrush="Transparent" BorderThickness="1"
Width="200" Height="200">
<StackPanel Width="200" Height="200">