我想借助滑块调整画布上的圆圈大小。这个圆圈可以通过我在代码后面做的一些拖放操作在画布上移动,所以它的位置不固定。
我已将滑块的值绑定到椭圆的高度和宽度。不幸的是,当我使用滑块时,圆圈的左上角(实际上是它所在的矩形的左上角)会在操作过程中保持相同的大小。
我希望在操作期间将中心点保持不变来调整大小。在XAML中有一个简单的方法吗?顺便说一下,我已经尝试过ScaleTransform,但它并没有完全按照我的意愿行事。
非常感谢! : - )
扬
<Canvas x:Name="MyCanvas">
<!-- this is needed for some adorner stuff I do in code behind -->
<AdornerDecorator Canvas.Left="10"
Canvas.Top="10">
<Ellipse x:Name="myEllipse"
Height="{Binding Path=Value, ElementName=mySlider}"
Width="{Binding Path=Value, ElementName=mySlider}"
Stroke="Aquamarine"
Fill="AliceBlue"
RenderTransformOrigin="0.5 0.5">
<Ellipse.RenderTransform>
<RotateTransform Angle="{Binding Path=Value, ElementName=myRotationSlider}" />
</Ellipse.RenderTransform>
</Ellipse>
</AdornerDecorator>
<Slider x:Name="mySlider"
Maximum="100"
Minimum="0"
Width="100"
Value="10"
Canvas.Left="150"
Canvas.Top="10" />
<Slider x:Name="myRotationSlider"
Maximum="360"
Minimum="0"
Width="100"
Value="0"
Canvas.Left="150"
Canvas.Top="50" />
</Canvas>
答案 0 :(得分:4)
您可以通过ValueConverter将Canvas.Left和Canvas.Top绑定到高度和宽度。
具体(编辑):
为Canvas.Left和Canvas.Top创建一个属性并绑定到这些属性
存储Width和Heigth的旧值或旧滑块值
每当更改滑块时,通过减去存储的值来获得增量变化“dx”
(不要忘记更新储值......)
将dx添加到宽度和高度属性
并且,如Will所说,将dx / 2 * -1添加到Canvas.Left和Canvas.Top属性。
这有意义吗?
答案 1 :(得分:2)
问题是您正在使用SLIDER来调整宽度和高度。 RenderTransformOrigin不计算宽度和高度;只有RenderTransforms才能使用该值。
这是一个更正版本(brb,kaxaml):
<Canvas x:Name="MyCanvas">
<!-- this is needed for some adorner stuff I do in code behind -->
<AdornerDecorator Canvas.Left="50" Canvas.Top="50">
<Ellipse
x:Name="myEllipse"
Width="10"
Height="10"
Fill="AliceBlue"
RenderTransformOrigin="0.5 0.5"
Stroke="Aquamarine">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="{Binding Path=Value, ElementName=myRotationSlider}"/>
<ScaleTransform
CenterX=".5"
CenterY=".5"
ScaleX="{Binding Path=Value, ElementName=mySlider}"
ScaleY="{Binding Path=Value, ElementName=mySlider}"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</AdornerDecorator>
<Slider
x:Name="mySlider"
Width="100"
Canvas.Left="150"
Canvas.Top="10"
Maximum="10"
Minimum="0"
SmallChange=".01"
Value="1"/>
<Slider
x:Name="myRotationSlider"
Width="100"
Canvas.Left="150"
Canvas.Top="50"
Maximum="360"
Minimum="0"
Value="0"/>
</Canvas>
当然,这可能不适合你。为什么?我使用的ScaleTransform不仅可以缩放圆形,还可以缩放边框;随着圆圈变大,边界也会变大。希望你不会关心这个。
此外,在组合变换(在这种情况下缩放然后旋转)时,实现它们按顺序应用,并且可能影响另一个变换的方式。在你的情况下,你不会注意到这一点。但是,如果你正在进行轮换和翻译,那么订单就是相关的。
<Canvas x:Name="MyCanvas">
<!-- this is needed for some adorner stuff I do in code behind -->
<Grid Width="100" Height="100">
<AdornerDecorator>
<Ellipse
x:Name="myEllipse"
Width="{Binding Path=Value, ElementName=mySlider}"
Height="{Binding Path=Value, ElementName=mySlider}"
Fill="AliceBlue"
RenderTransformOrigin="0.5 0.5"
Stroke="Aquamarine">
<Ellipse.RenderTransform>
<RotateTransform Angle="{Binding Path=Value, ElementName=myRotationSlider}"/>
</Ellipse.RenderTransform>
</Ellipse>
</AdornerDecorator>
</Grid>
<Slider
x:Name="mySlider"
Width="100"
Canvas.Left="150"
Canvas.Top="10"
Maximum="100"
Minimum="0"
Value="10"/>
<Slider
x:Name="myRotationSlider"
Width="100"
Canvas.Left="150"
Canvas.Top="50"
Maximum="360"
Minimum="0"
Value="0"/>
</Canvas>
答案 2 :(得分:2)
由于您使用的是Canvas,因此元素所在的位置就是位置。如果你想要改变Top,Left位置,你需要自己动手。如果您使用其他面板类型(如网格),则可以更改椭圆的对齐方式,以便将其放在相同的相对位置,无论大小如何。你可以通过在AdornerDecorator中添加一个Grid并使Ellipse居中来获得该效果,但是你还需要将AdornerDecorator或Grid设置为固定大小,因为它们不会在Canvas中拉伸。
您可以使用的最佳解决方案是应用于RenderTransform属性的ScaleTransform,其RenderTransformOrigin为0.5,0.5。你说你有ScaleTransform的问题但不是问题所在。
答案 3 :(得分:1)
将椭圆包裹在最大尺寸的网格中。只要它更小,椭圆将在网格中居中:
<Grid
Canvas.Left="10"
Canvas.Top="10"
Width="100"
Height="100">
<AdornerDecorator>
<Ellipse x:Name="myEllipse"
Height="{Binding Path=Value, ElementName=mySlider}"
Width="{Binding Path=Value, ElementName=mySlider}"
Stroke="Aquamarine"
Fill="AliceBlue"
RenderTransformOrigin="0.5 0.5">
<Ellipse.RenderTransform>
<RotateTransform Angle="{Binding Path=Value, ElementName=myRotationSlider}" />
</Ellipse.RenderTransform>
</Ellipse>
</AdornerDecorator>
</Grid>
您可能需要调整拖动逻辑来处理拖动网格而不是椭圆本身。
答案 4 :(得分:0)
我在简单的XAML中找到了一种非常简单的方法:设置Margin="-1000000"
。在此处阅读更多内容:Positioning an element inside the Canvas by its center (instead of the top left corner) using only XAML in WPF