2009-11-08 19 views
6

Ich benutze Silverlight 3/C#, und ich versuche, einige XAML-Objekte als Reaktion auf einen Benutzer auf eine Schaltfläche programmatisch zu erstellen.Wie programmiere ich eine Leinwand in Silverlight?

Allerdings kann ich nicht ein Canvas Objekt zu positionieren scheinen die ich geschaffen habe - wenn ich SetValue() auf dem neuen Canvas mit dem Canvas.LeftProperty Wert aufrufen, löscht der Browser-Fenster auf einen leeren Bildschirm.

ich eine einfache Funktion, die das Problem aufweist (Ich begann mit etwas komplexer):

private Canvas MakeNewCanvas() 
    { 
     Canvas newCanvas = new Canvas(); 
     newCanvas.Width = newCanvas.Height = 50; 
     newCanvas.SetValue(Canvas.LeftProperty, 10); 
     return newCanvas; 
    } 

und einem einfachen Button-Klick-Handler, der diese Anrufe:

private void MyButton_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     myPage.Children.Add(MakeNewCanvas()); 
    } 

NB : myPage ist ein Canvas-Objekt, das in der MainPage XAML-Datei meiner App definiert ist.

Ich habe dies in der VS-Debugger mit der SL-Anwendung in Firefox ausgeführt, und wenn es die Zeile SetValue() ausführt, wird der Browser weiß und beginnt zu versuchen, Daten zu downloaden (gemäß der Statusleiste). Ich habe versucht Aufruf SetValue(), nachdem ich die Canvas im XAML Baum mit so etwas wie gesetzt haben:

myPage.Children.Add(newCanvas); 
    newCanvas.SetValue(Canvas.LeftProperty, 10); 

aber es macht keinen Unterschied - sobald der SetValue() Anruf getroffen wird, geht der Browser weiß.

Die Klasse Canvas scheint keine direkte Methode zur Einstellung von Left/Top auf sich zu haben, abgesehen von der SetValue()-Funktion mit Abhängigkeitseigenschaften enum-Werten. Es gibt auch Canvas.SetLeft() und Canvas.SetTop(), aber ich denke, sie sind nur Shims auf SetValue(). Sie zu benutzen, hat sowieso nicht geholfen.

Wenn ich nicht SetValue() aufrufen, dann erscheint meine Leinwand (und Kind-Objekte, die ich hinzugefügt habe) in der SL-App, wie Sie vielleicht erwarten, ganz oben links.

Wenn ich erstellen und Position ein Canvas Objekt in Expression Blend, dann ist die XAML generiert enthält Canvas.Left und Canvas.Top Eigenschaftswerte auf den Canvas selbst, wie ich erwarten würde, so scheint es mir, dass das, was ich in C# versuchen sollte Arbeit.

Aber ich bin nicht in der Lage, die linken/oberen Werte selbst aus C# zu setzen, ohne dass der SL im Browser ganz komisch wird.

Irgendwelche Ideen?

Edit: mein Ansatz ist richtig, aber Leinwand Coords müssen Fließkomma, nicht ganzzahlig sein - siehe akzeptierte Antwort für Details.

Antwort

13

Der Versuch, Ihren Code, aber mit der Debugger Ausnahmen fangen, die ich erhalten:

DependencyProperty vom Typ System.Double kann nicht auf ein Objekt vom Typ System.Int32 eingestellt werden.

was ist eine wirklich dumme Gotcha - SetValue nimmt nur Objekt, so dass Sie anfällig für ein Problem wie folgt sind.

Versuchen entweder:

newCanvas.SetValue(Canvas.LeftProperty, 10.0); 

oder

Canvas.SetLeft(newCanvas, 10); 

und es wird wahrscheinlich funktionieren.

+1

+1 Guter Fang, gut entdeckt – AnthonyWJones

2

Das Verhalten der angehängten Eigenschaften kann zunächst etwas verwirrend sein. Die Eigenschaften Canvas.LeftProperty und Canvas.TopProperty werden auf untergeordnete Objekte einer Zeichenfläche angewendet. Sie sind daher nur sinnvoll, wenn das Kindobjekt auf eine Canvas platziert wird. Es ist wichtig zu verstehen, dass sich die in WPF/SL-Objekten nicht selbst positionieren, sondern bis zum umgebenden Panel, um zu entscheiden, wo sie abgelegt werden sollen.

Ich vermute, die myPage nicht der Canvas-Typ ist, ist es wahrscheinlich ein Grid, daher wäre es keine Ahnung, was mit solchen Eigenschaften zu tun, auch wenn es für sie zu suchen gestört (was es nicht).

Damit Sie Ihr neues Canvas spezifisch positionieren können, müssen Sie es zu einem Canvas hinzufügen.

+0

Ja, ich habe ein paar Minuten gebraucht, um das herauszufinden (Canvas-Eigenschaften gelten für untergeordnete Objekte von Canvas), aber das weiß ich. myPage ist ein Canvas, wie in meinem XAML definiert, und ich habe gerade this.myPage im VS-Debugger untersucht, um sicherzustellen, dass ich das neue Canvas als untergeordnetes Element hinzufüge. VS hat gemeldet, dass myPage tatsächlich ein Canvas-Objekt ist. – Slacker

Verwandte Themen