15

WPF キャンバスには、コントロールの左上の (0,0) から始まる座標系があります。

たとえば、次のように設定すると、コントロールが左上に表示されます。

<Control Canvas.Left="0" Canvas.Top="0">

標準のデカルト座標に変更するにはどうすればよいですか?

基本的:

  • (0,0) 中心
  • Y を反転

この投稿は似ていることに気付きましたが、座標系の変換については触れていません。TranslateTransform を追加しようとしましたが、機能しません。

4

4 に答える 4

30

カスタム パネルを作成する必要はありません。キャンバスはうまくいきます。別のコントロール (ボーダーなど) 内にラップし、中央に配置し、サイズをゼロにして、RenderTransform で反転するだけです。

<Border>
  <Canvas HorizontalAlignment="Center" VerticalAlignment="Center"
          Width="0" Height="0"
          RenderTransform="1 0 0 -1 0 0">
    ...
  </Canvas>
</Border>

これを行うと、(0,0) が含まれているコントロールの中心 (この場合は境界線の中心) になり、+Y が下ではなく上になることを除いて、キャンバス内のすべてが表示されます。

この場合も、カスタム パネルを作成する必要はありません。

于 2009-12-27T05:24:44.527 に答える
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;
    }
}
于 2009-12-10T02:36:48.493 に答える
7

Origin は で簡単に変更できます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>
于 2014-01-06T01:14:40.447 に答える
5

最も良い方法は、カスタム Canvas を作成することです。その中で、0,0 を中心とするような方法で ArrangeOverride を作成できます。

更新:以下の回答で別のコメントを与えました (@decasteljau) Canvas から派生することはお勧めしません。Panel から派生し、2 つの Attached Dependancy プロパティ Top と Left を追加して、上に貼り付けたのと同じコードを配置できます。また、LayoutTransform を含むコンストラクターは必要ありません。また、パネル コードで変換を使用しないでください。適切な測定を使用し、パネルの DesiredSize に基づいて配置します。これにより、優れたコンテンツ サイズ変更動作も得られます。Canvas のサイズが変更された場合、Canvas は項目を動的に配置しません。

于 2009-12-09T04:18:09.677 に答える