Entwickler-Ecke

WPF / Silverlight - Ellipse mit Canvas skalieren


Christian S. - Fr 04.05.07 18:07
Titel: Ellipse mit Canvas skalieren
Hallo!

Ich habe ein Canvas und darauf eine Ellipse. Ich möchte nun, dass wenn die Canvas vergrößert / verkleinert wird, die Ellipse mitskaliert. Sollte in WPF ja möglich sein. Ich hatte es so versucht:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
el = new Ellipse();
Canvas.SetLeft(el, 0);
Canvas.SetTop(el, 0);

el.Width = 50;
el.Height = 50;

el.VerticalAlignment = VerticalAlignment.Stretch;
el.HorizontalAlignment = HorizontalAlignment.Stretch;

el.Fill = ...;

myCanvas.Children.Add(el);


Aber das scheint zu reichen. Wie macht man das also?

Grüße
Christian


Kha - Fr 04.05.07 20:12

So langsam nimmt WPF wohl Fahrt auf :D ...

Canvas ist ein besonderes Panel, denn es kümmert sich als einziges überhaupt nicht um sein Layout und damit auch nicht um das seiner Child-Elemente(weswegen jede Canvas auch per Default 0 Pixel breit und hoch ist[meta]Äußerst lustig, wenn man versucht, die Hintergrundfarbe der Canvas zu setzten[/meta]), der einzige Einfluss ist eben durch die zwei attached Properties Left und Top möglich; damit ist ein Canvas-Objekt aber auch ziemlich lightweight. Für minimales Layout würde ich ein einzelliges Grid benutzen (der Standard für Grids, es genügt also ein "new Grid()" und "Children.Add(...)").


Christian S. - Fr 04.05.07 20:49

user profile iconKhabarakh hat folgendes geschrieben:
So langsam nimmt WPF wohl Fahrt auf :D ...
Ich hab jetzt endlich mal ein Programm, wo das wirkliche Vorteile bietet :-)

Mit dem Grid funktionieren jetzt HorizontalAlign und VerticalAlign so, wie sie sollen, wenn man Margin benutzt, anstatt Höhe und Breite zu setzen.

Leider habe ich einen Denkfehler :-( Wenn ich das Grid um 50 Pixel verkleinere, so wird nun auch die Ellipse um 50px verkleinert. Und dann ist sie weg :lupe:

Ich bräuchte also eine Möglichkeit, dass wenn ich das Grid um 10% verkleinere, auch die Ellipse um 10% verkleinert. Gibt's da was automatisches oder muss ich selber implementieren.

//edit: Im SizeChanged-Event des Grids selber zeichnen geht natürlich, aber ich habe ja die Hoffnung, dass es was von Rati ... äh ... WPF gibt.


Kha - Fr 04.05.07 22:03

Ich hatte gedacht, du wolltest die Ellipse das gesamte Grid ausfüllen lassen, weil du *Alignment auf Stretch gesetzt hast. Nun bin ich mir leider nicht mehr ganz so sicher, was du vorhast ^^ . Willst du die Ellipse mit einem Rand umgeben (zentriert oder auch nicht), sodass sowohl Ellipse als auch Rand proportional zum Grid skaliert werden? Falls das so (wenigstens in etwa) stimmen sollte, hier einmal zwei Vorschläge:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
<!-- Ellipse mit jeweils 10% Abstand nach rechts und unten -->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition />
    </Grid.RowDefinitions>
    <!-- Vorschlag 1 - Grid -->
    <Grid Background="Gray">
      <Grid.RowDefinitions>
        <RowDefinition Height="9*"/>
        <RowDefinition Height="*"/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="9*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Ellipse Fill="Black" Stroke="Red"/>
    </Grid>
    <!-- banaler Vorschlag 2 - Viewbox -->
    <Viewbox Grid.Row="1" Stretch="Fill">
      <Ellipse Width=".9" Height=".9" Fill="Black" Margin="0,0,.1,.1" Stroke="Red" StrokeThickness=".01"/>
    </Viewbox>

    <GridSplitter Height="10" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Row="1"/>
  </Grid>
</Page>


Christian S. - Fr 04.05.07 22:23

Um genau zu sein, möchte ich ein Backgammon-Brett zeichnen mit entsprechenden Steinen (= Ellipsen) drauf. Und wenn ich das Fenster kleiner mache und somit das Brett, sollen auch die Steine im selben Maße kleiner werden.

Leider müssen die Steine hinterher auch von einer Stelle auf dem Brett zur anderen wandern (animiert), sodass Dein Grid-Vorschlag wohl eher unpraktisch sein dürfte.

Ich schau mir dann mal an, was eine Viewbox ist ;-)

Vielen Dank schonmal :zustimm:


Kha - Fr 04.05.07 23:55

Eine Viewbox wird nicht gerade häufig fürs Layout benutzt, da es oft zwar durchaus erwünscht ist - wie in deinem Beispiel - dass sich die Inhalte der veränderten Größe ihres Containers anpassen, aber meistens eher weniger, dass dazu einfach die ganzen Child-Controls wie mit einer Lupe vergrößert werden, also mit Textgröße usw. (oder in meinem Beispiel die Stroke-Größe), weswegen ich dir auch erst das Grid vorgeschlagen habe. Für ein Spielfeld, das ja nichts anderes als eine große Zeichnung ist, wäre eine Viewbox dann imho allerdings ideal.
Ich würde deshalb vorschlagen:

Quelltext
1:
2:
3:
4:
5:
6:
Viewbox[Stretch=Uniform]
  Grid
    Spielplan
    Canvas
      Steine(Ellipse)
      ...

Viele Ellipsen sind zwar nicht ganz so elegant, aber bei Weitem nicht so schlimm wie etwa mehrere sich bewegende TImages und ein paar Backgammon-Steinchen dürften WPF wohl kaum in die Knie zwingen.


Christian S. - Sa 05.05.07 00:24

Genial! Das war die Lösung! :dance2:

WPF beeindruckt mich immer mehr. Habe gerade DataTemplates für meine Listboxen eingesetzt. Wenn ich überlege, wie doof das immer war, die Items selber zeichnen zu müssen. Und jetzt reichen ein paar XAML-Tags :shock:


Kha - Sa 05.05.07 13:17

Jupp, WPF macht einfach Spaß und wäre fast schon erschreckend genial, gäbe es da nicht noch ein paar Macken in v1 und noch ziemlich dürftigen Toolsupport. Man kann sich überhaupt nicht mehr vorstellen, wie Programmierer so viele Jahre ohne lookless Controls überleben konnten ;) .
Da WPF aber eben nicht nur eine kleine neue UI-API ist, ist der Einstiegsaufwand nicht zu vergleichen mit z.B. Winforms. Dependency/attached Properties, Routed Event Handling (Tunneling/Bubbling), Property Inheritance, Visual/Logical Tree, Styling/Templating/Themeing, Triggers/Animations, ... , alles kein Pappenstiel.