在我的 .NET 4.8 WPF 应用程序中,我有一个带有两个
ContainerVisual
元素的窗口:
_rootContainerVisual
_containerVisualToRotate
是
_rootContainerVisual
的孩子
在实际应用程序中以某种方式彼此相邻的多个精灵上显示多个图像。
在提供的示例代码中显示填充画笔。
内容比两者的尺寸都大
ContainerVisual
我想围绕 z 轴旋转完整的 _containerVisualToRotate。
当我这样做时,我注意到 _containerVisualToRotate 内的部分图像/画笔被剪切,尽管有足够的空间。
在标准 WPF 中,我使用负边距来使其工作。 示例 xaml(不需要后面的代码):
<Window x:Class="PlayingAroundInWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PlayingAroundInWpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" MouseEnter="Window_MouseEnter" MouseLeave="Window_MouseLeave">
<Grid Background="AntiqueWhite">
<Grid x:Name="mainGrid" RenderTransformOrigin="0.5,0.5" Margin="-100">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="15"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Rectangle Fill="LightBlue" Opacity="0.2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Label HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72">Test with standard WPF</Label>
</Grid>
</Grid>
</Window>
这会导致以下结果:内部内容大于视图的可见部分 -> 内部内容在旋转过程中不会被剪切。
我尝试用
_containerVisualToRotate
by 做类似的事情
使用带负数的 Clip 属性。
将 _containerVisualToRotate 的 Size 属性设置为一个较大的数字
将相对大小调整设置为值 >5.0f
将矩形的 Size 属性设置为一个较高的数字
然而,这一切都没有达到预期的结果。
这是我的示例代码(xaml 实际上是一个空窗口):
public partial class ContainerVisualExample : Window
{
private IntPtr _hwndHost;
private Windows.UI.Composition.Compositor _compositor;
private Windows.UI.Composition.CompositionTarget _target;
private Windows.UI.Composition.ContainerVisual _rootContainerVisual;
private Windows.UI.Composition.ContainerVisual _containerVisualToRotate;
public ContainerVisualExample()
{
InitializeComponent();
Loaded += ContainerVisualExample_Loaded;
}
private void ContainerVisualExample_Loaded(object sender, RoutedEventArgs e)
{
SetupCompositions();
AddRectangleToContainer();
RotateContainerVisual();
}
private void SetupCompositions()
{
_hwndHost = new System.Windows.Interop.WindowInteropHelper(this).Handle;
_compositor = new Compositor();
_target = _compositor.CreateDesktopWindowTarget(_hwndHost, false);
// Setup the _rootContainerVisual.
_rootContainerVisual = _compositor.CreateContainerVisual();
_rootContainerVisual.RelativeSizeAdjustment = Vector2.One;
_rootContainerVisual.Offset = new Vector3(0, 0, 0);
_containerVisualToRotate = _compositor.CreateContainerVisual();
_containerVisualToRotate.RelativeSizeAdjustment = new Vector2(5.0f, 5.5f);
_containerVisualToRotate.Offset = new Vector3(0, 0, 0);
_containerVisualToRotate.Size = new Vector2(10000, 10000);
_containerVisualToRotate.Clip = _compositor.CreateInsetClip(-10000, -10000, -10000, -10000);
_containerVisualToRotate.CenterPoint = new Vector3(400, 225, 0);
_rootContainerVisual.Children.InsertAtTop(_containerVisualToRotate);
_target.Root = _rootContainerVisual;
}
private void AddRectangleToContainer()
{
// Create a rectangle element
Windows.UI.Composition.SpriteVisual rectangleVisual = _compositor.CreateSpriteVisual();
rectangleVisual.Size = new Vector2(10000, 10000);
// Set the fill color of the rectangle to light blue
Windows.UI.Color lightBlueColor = Windows.UI.Color.FromArgb(255, 173, 216, 230);
Windows.UI.Composition.CompositionColorBrush fillBrush = _compositor.CreateColorBrush(lightBlueColor);
rectangleVisual.Brush = fillBrush;
// Add the rectangle to the _containerVisualToRotate
_containerVisualToRotate.Children.InsertAtTop(rectangleVisual);
}
private void RotateContainerVisual()
{
_containerVisualToRotate.RotationAngleInDegrees = 45.0f;
}
}
但是,这仍然会导致削波:
现在,我不知道如何让它发挥作用。
正如我上面所写:旋转内部内容(在示例中为矩形)并不是真正的选择,因为它包含多个精灵,这些精灵都需要围绕同一中心点单独旋转。
还有其他办法吗?
我无法添加评论, 你试过了吗
LayoutTransform
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="15"/>
<TranslateTransform/>
</TransformGroup>
</Grid.LayoutTransform>
public partial class ContainerVisualExample : Window
{
private Windows.UI.Composition.Compositor _compositor;
private Windows.UI.Composition.ContainerVisual _rootContainerVisual;
private Windows.UI.Composition.ContainerVisual _containerVisualToRotate;
public ContainerVisualExample()
{
InitializeComponent();
Loaded += ContainerVisualExample_Loaded;
}
private void ContainerVisualExample_Loaded(object sender, RoutedEventArgs e)
{
SetupCompositions();
AddRectangleToContainer();
RotateContainerVisual();
AdjustRootContainerSize();
}
private void SetupCompositions()
{
// Create a Compositor instance
_compositor = new Compositor();
// Create the root ContainerVisual
_rootContainerVisual = _compositor.CreateContainerVisual();
_rootContainerVisual.RelativeSizeAdjustment = Vector2.One;
// Create the ContainerVisual to rotate
_containerVisualToRotate = _compositor.CreateContainerVisual();
_containerVisualToRotate.RelativeSizeAdjustment = Vector2.One;
// Add the ContainerVisuals to the visual tree
ElementCompositionPreview.SetElementChildVisual(mainCanvas, _rootContainerVisual);
_rootContainerVisual.Children.InsertAtTop(_containerVisualToRotate);
}
private void AddRectangleToContainer()
{
// Create a solid color brush
var brush = _compositor.CreateColorBrush(Windows.UI.Colors.LightBlue);
// Create a SpriteVisual to represent the rectangle
var rectangleVisual = _compositor.CreateSpriteVisual();
rectangleVisual.Size = new Vector2(300, 200); // Set size as per your requirement
rectangleVisual.Brush = brush;
// Add the rectangle to the container to rotate
_containerVisualToRotate.Children.InsertAtTop(rectangleVisual);
}
private void RotateContainerVisual()
{
// Rotate the _containerVisualToRotate
var rotationAnimation = _compositor.CreateScalarKeyFrameAnimation();
rotationAnimation.InsertKeyFrame(1.0f, 360.0f, _compositor.CreateLinearEasingFunction());
rotationAnimation.Duration = TimeSpan.FromSeconds(5);
rotationAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
_containerVisualToRotate.StartAnimation(nameof(Visual.RotationAngleInDegrees), rotationAnimation);
}
private void AdjustRootContainerSize()
{
// Adjust the size of _rootContainerVisual to accommodate the rotated content
var size = new Vector2(400, 300); // Adjust as per your content size
_rootContainerVisual.Size = size;
}
}
我们创建一个 Compositor 实例并初始化根和子 ContainerVisuals。 将矩形视觉对象添加到 _containerVisualToRotate 来表示要旋转的内容。 我们将旋转动画应用于 _containerVisualToRotate。 调整 _rootContainerVisual 大小以适应旋转的内容。 您需要确保为 Windows.UI.Composition 命名空间导入必要的引用和命名空间。此外,mainCanvas 应该是 XAML 文件中要在其中显示合成视觉效果的画布的名称。根据您的应用程序要求调整视觉效果的大小和内容。