Entwickler-Ecke

WPF / Silverlight - Mehrere UI-Elemente in einem Canvas


mmp5 - Do 18.03.10 00:30
Titel: Mehrere UI-Elemente in einem Canvas
Also ... Folgendes Problem:

ich möchte auf eine FixedPage (welche in einem DocumentViewer) dargestellt wird mehrere Rectangles anzeigen ...
klingt ja nicht schwer ;)
Man kann die Rectangles entweder direkt auf die FixedPage packen oder diese zunächst in einem Container(Canvas) packen.

ich habe da mal was vorbereitet:
Es wird Statt 50 nur 1 Rechteck angezeigt? warum?



C#-Quelltext
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:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
        
        private void button1_Click(object sender, RoutedEventArgs e)
        {

            fill50Rects();
      
            DocumentViewer docView1 = new DocumentViewer();
            try
            {
                grid1.Children.Remove(docView1);
            }
            catch (Exception) { }
            PageContent pc = new PageContent(); 
            FixedPage fp = new FixedPage();

            // --- Wichtiger Teil ------------------------------------------
            Canvas c1 = new Canvas();
            for (int i = 0; i < LRec.Count; i++)
            {
                c1.Children.Add(LRec[i]);  
            }
            fp.Children.Add(c1);[/b]
            // -------------------------------------------------------------
            ((IAddChild)pc).AddChild(fp);
            FixedDocument fixDoc1 = new FixedDocument();
            fixDoc1.Pages.Add(pc);
            ((IAddChild)docView1).AddChild(fixDoc1);
            grid1.Children.Add(docView1);
  }
  
        List<Rectangle> LRec = new List<Rectangle>();
        List<Canvas> LCan = new List<Canvas>();
  //Fülle LRec und LCan
        private void fill50Rects()
        {
            //Rectangles
            for (int i = 0; i < 50; i++)
            {
                Random rand = new Random(3);
                Rectangle tmpRec = new Rectangle();
                tmpRec.Fill = Brushes.Black;
                tmpRec.Margin = new Thickness(rand.Next(0400), rand.Next(0400), 00);
                tmpRec.Width = 40;
                tmpRec.Height = 40;
                tmpRec.Name = "Rec" + i.ToString();
                LRec.Add(tmpRec);
            }
  }


Christian S. - Do 18.03.10 00:46

Also was mir jetzt auf Anhieb auffällt: Wenn Du 50mal die Random-Klasse instanziert (einmal reicht) und dann auch noch einen festen Seed-Wert angibst, wie zufällig werden die Ergebnisse dann Deiner Meinung nach? ;-)

Mit anderen Worten: Sicher, dass die 50 Rectangles nicht einfach alle übereinander liegen?


danielf - Do 18.03.10 09:38

Hallo,

also das ist jedenfalls falsch. Die Random-Klasse solltest du nur einmal instantiieren, ansonsten liefert sie gleiche Werte. Einfach aus der For-Schleife raus.

Gruß Daniel


mmp5 - Sa 10.04.10 18:16

Also ihr habt mich da mal ganz falsch verstanden ;) oder ich hab mich falsch ausgedrückt ...
und um die Random-klasse ging es hier gar nicht ...

ALSO ... das Problem lag darin, dass ich die rectangles ... in einem Fixed document darstellen wollte und wenn der Documentinhalt sich geändert hat die Rectangles wieder dargestellt werden ...

Ich hatte ein WPF verständnisproblem ... da ich gedacht habe, wenn ich das Fixed Document -> sprich den DocumentViewer lösche, dann würden sich die Rectangles auch davon lösen und frei werden ... waren sie aber natürlich nicht ...

Lösung: ich speichere jetzt nur die Koordinaten und die größe des einzelnen Rectangles und wenn ich ein neues DOcument darstelle, lasse ich die Rectangles einfach neu berechnen und darstellen ...

daher stellt sich eine Grundlegende WPF frage:
Wie kann ich UIElemente einfach kopieren?
oder muss man das über den Umweg machen, den ich gewählt habe?


Kha - Sa 10.04.10 23:30

Verschieben kannst du Elemente nur, indem du sie aus dem einen Parent löschst und in einen anderen einfügst. Da WPF aber darauf ausgelegt ist, die UI gar nicht speziell zu behandeln, sondern 1:1 aus den Daten erstellen zu lassen (Stichwort MVVM), dürfte dein neuer Ansatz passender sein.