Pergunta

A lona WPF tem um sistema de coordenadas a partir de (0,0) na parte superior esquerda do controle.

Por exemplo, definindo o seguinte fará meu controle aparece no canto superior esquerdo:

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

Como posso alterá-lo para o padrão coordenadas cartesianas ?

Basicamente:

  • (0,0) no centro
  • aleta Y

notei este post é semelhante, mas não fala sobre a tradução do sistema de coordenadas. Eu tentei adicionar um TranslateTransform, mas não posso fazê-lo funcionar.

Foi útil?

Solução

A melhor coisa é escrever uma lona personalizada, na qual você pode escrever ArrangeOverride de tal forma a que leva 0,0 como o centro.

Update: eu tinha dado outro comentário na abaixo de resposta (@decasteljau) I rotina recomendar decorrente da tela, você pode derivar de Panel e adicionar duas propriedades dependência anexados superior e esquerda e colocar o mesmo código que você colou acima. Também necessidade does not um construtor com LayoutTransform nele e uso não faça qualquer transformar no painel Use cupom medida adequada e organizar baseado no DesiredSize do painel Para que você possa obter bom comportamento de redimensionamento de conteúdo também. Canvas não dinamicamente itens de posição quando as mudanças de tamanho da tela.

Outras dicas

Não há necessidade de criar um painel personalizado. Canvas vai fazer muito bem. Basta enrolar-lo dentro de outro controle (como uma fronteira), o centro-lo, dar-lhe tamanho zero, e lançá-lo com um RenderTransform:

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

Você pode fazer isso e tudo na tela ainda aparecerá, exceto (0,0) estarão no centro do controle que contém (neste caso, o centro da Fronteira) e + Y será até em vez de para baixo.

Mais uma vez, há não há necessidade para criar um painel personalizado para isso.

Foi muito fácil de fazer. Olhei para o Código da lona originais usando .NET Reflector, e notou a implementação é realmente muito simples. A única coisa necessária era para substituir a função 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;
    }
}

Você pode simplesmente mudar a Origem com 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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top