WPF: jak zrobić (0,0) w środku wewnątrz płótna
Płótno WPF ma układ współrzędnych zaczynający się od (0,0) w lewym górnym rogu kontrolki.
Na przykład ustawienie następującej opcji spowoduje, że moja kontrolka pojawi się w lewym górnym rogu:
<Control Canvas.Left="0" Canvas.Top="0">
Jak mogę zmienić go na standardowy współrzędne kartezjańskie ?
W zasadzie:
- (0,0) w centrum
- flip Y
Zauważyłem ten post jest podobny, ale nie mówi o tłumaczeniu układu współrzędnych. I próbowałem dodać TranslateTransform, ale nie mogę tego zrobić.
4 answers
Najlepiej jest napisać własne Płótno, w którym można pisać tak, że zajmuje 0,0 jako środek.
Update: dałem kolejny komentarz w Odpowiedzi poniżej (@decasteljau) nie polecam czerpać z Canvas, można czerpać z panelu i dodać dwa dołączone właściwości zależności Góra i lewo i umieścić ten sam kod, który wkleiłeś powyżej. Nie wymaga również konstruktora z LayoutTransform w nim, i nie używa żadnej transformacji w kodzie panelu użyj właściwego Zmierz i ułóż na podstawie pożądanego rozmiaru panelu, aby uzyskać ładne zachowanie zmiany rozmiaru zawartości. Obszar roboczy nie pozycjonuje dynamicznie elementów Po zmianie rozmiaru obszaru roboczego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-27 08:49:14
Nie ma potrzeby tworzenia własnego panelu.Płótno wystarczy. Po prostu zawiń ją wewnątrz innej kontrolki( takiej jak obramowanie), wyśrodkuj ją, nadaj jej zerowy rozmiar i odwróć ją za pomocą RenderTransform:
<Border>
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center"
Width="0" Height="0"
RenderTransform="1 0 0 -1 0 0">
...
</Canvas>
</Border>
Możesz to zrobić i wszystko w obszarze roboczym nadal będzie wyświetlane, z wyjątkiem (0,0) będzie w środku kontrolki zawierającej (w tym przypadku w środku granicy) i +Y będzie w górę zamiast w dół.
Ponownie, nie ma potrzeby tworzenia niestandardowego panel do tego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-27 05:32:08
To było bardzo łatwe do zrobienia. Spojrzałem na oryginalny kod Canvasa używając. NET Reflector i zauważyłem, że implementacja jest naprawdę bardzo prosta. Jedyną rzeczą wymaganą było nadpisanie funkcji 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;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-10 02:36:48
Możesz po prostu zmienić pochodzenie za pomocą 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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-06 12:49:45