WPF Canvas的坐标系从控件左上角的(0,0)开始。
例如,设置以下内容将使我的控件显示在左上角:
<Control Canvas.Left="0" Canvas.Top="0">
如何将其更改为标准cartesian coordinates?
基本上:
我注意到this post是相似的,但它没有谈到翻译坐标系。我尝试添加TranslateTransform,但我无法使其正常工作。
答案 0 :(得分:26)
无需创建自定义面板。 Canvas会做得很好。只需将其包装在另一个控件(如边框)中,居中,将其设置为零,然后使用RenderTransform翻转它:
<Border>
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center"
Width="0" Height="0"
RenderTransform="1 0 0 -1 0 0">
...
</Canvas>
</Border>
你可以这样做,画布上的所有内容仍然会出现,除了(0,0)将位于包含控件的中心(在这种情况下,边框的中心)和+ Y将会向上而不是下来。
同样,无需为此创建自定义面板。
答案 1 :(得分:7)
这很容易做到。我使用.NET Reflector查看了原始的Canvas代码,并注意到实现非常简单。唯一需要的是覆盖函数ArrangeOverride(...)
public class CartesianCanvas : Canvas
{
public CartesianCanvas()
{
LayoutTransform = new ScaleTransform() { ScaleX = 1, ScaleY = -1 };
}
protected override Size ArrangeOverride( Size arrangeSize )
{
Point middle = new Point( arrangeSize.Width / 2, arrangeSize.Height / 2 );
foreach( UIElement element in base.InternalChildren )
{
if( element == null )
{
continue;
}
double x = 0.0;
double y = 0.0;
double left = GetLeft( element );
if( !double.IsNaN( left ) )
{
x = left;
}
double top = GetTop( element );
if( !double.IsNaN( top ) )
{
y = top;
}
element.Arrange( new Rect( new Point( middle.X + x, middle.Y + y ), element.DesiredSize ) );
}
return arrangeSize;
}
}
答案 2 :(得分:6)
您只需使用RenderTransformOrigin
更改原点。
<Canvas Width="Auto" Height="Auto"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
答案 3 :(得分:5)
最好的方法是编写一个自定义Canvas,您可以在其中编写ArrangeOverride,以0,0为中心。
更新:我在下面的答案中给出了另一个评论(@decasteljau)我不推荐从Canvas派生,你可以从Panel派生并添加两个Attached Dependancy属性Top和Left并将你粘贴的相同代码放在上面。也不需要一个带有LayoutTransform的构造函数,并且不要在面板代码上使用任何变换使用适当的度量并根据面板的DesiredSize进行排列这样你就可以获得漂亮的内容调整大小行为。当画布大小更改时,Canvas不会动态定位项目。