Zunächst einmal gibt Height.Value 1 zurück, da Height eine GridLength ist, mit einem GridUnitType von Star. Die 1 stammt von der proportionalen Sternengröße (z. B. Height="2*", Height="3*", usw.). Das heißt, GridLength.Value kann nicht isoliert gelesen werden: Sie müssen es in Verbindung mit dem GridUnitType lesen.
Nun zum eigentlichen Problem. WPF berechnet die ActualHeight von Elementen nicht, bis sie gemessen werden, was es im Rahmen des Anzeigevorgangs tut. Aus den RowDefinition.ActualHeight-Dokumenten:
Wenn Sie Zeilen oder Spalten hinzufügen oder entfernen, wird die ActualWidth für alle ColumnDefinition-Elemente und die ActualHeight für alle RowDefinition-Elemente auf null, bis Measure aufgerufen wird.
Wenn Sie also versuchen, ActualHeight abzurufen, bevor WPF Measure aufgerufen hat, erhalten Sie 0 oder ein anderes schlechtes Ergebnis.
Glücklicherweise müssen Sie ActualHeight tatsächlich nicht abrufen: Weil WPF Ihr Objekt an den verfügbaren Platz anpassen wird (aufgrund der Sternengröße), kann das Objekt tatsächlich sein eigenes SizeChanged-Ereignis behandeln oder OnRenderSizeChanged überschreiben. Je nach Funktionsweise Ihrer Renderung kann dieser Ereignishandler das Set der Untergeordneten des Objekts aktualisieren (wenn das Objekt ein Panel- oder Zeichenobjekt ist) oder eine erneute Darstellung mit InvalidateVisual erzwingen (wenn das Objekt eher im Immediate-Mode-Stil zeichnet, z. B. indem OnRender überschrieben wird).
1 Stimmen
Wann rufen Sie ActualHeight auf? Es sieht aus wie ActualHeight sollte funktionieren, aber dies wird erst verfügbar sein, sobald das Raster ausgemessen und angelegt wurde.
0 Stimmen
@itowlson: Du hast recht, ich rufe es am falschen Ort auf, das Raster wurde noch nicht gezeichnet. Ich erstelle ein Objekt, das sich basierend auf der Größe seines Elternelements selbst zeichnet. Ich habe die draw Methode aufgerufen, wenn sich die Abhängigkeitseigenschaften CellHeight / CellWidth geändert haben. Im Konstruktor funktioniert es nicht, weil es bereits eine Referenz für das Elternelement hat. Wo würdest du empfehlen, die Breite / Höhe abzurufen?
1 Stimmen
Deine Zeile hat die Höhe *, sodass das enthaltene Objekt automatisch auf die Größe der Gitterzelle angepasst wird. Lass also das enthaltene Objekt sein eigenes SizeChanged-Ereignis behandeln oder OnRenderSizeChanged überschreiben. Dann musst du die ActualHeight überhaupt nicht abfragen, da du die Größeninformationen aus den Ereignisdaten erhalten kannst, was dein Objekt unabhängig vom Container macht.
0 Stimmen
@itowlson: Ich habe deine Methode verwendet, aber jetzt kann ich sie nicht neu zeichnen, wenn sich die Höhe ändert. Ich muss das Rendering auslösen, indem ich die Größe des Fensters ändere. Wie kann ich das erneute Aufrufen des Renderns in einer PropertyChangedCallBack-Methode simulieren?
0 Stimmen
@itowlson: Übrigens, du solltest die Antwort als Antwort einstellen, damit ich sie als korrekt markieren kann.
0 Stimmen
@itowlson: Vergiss es, ich habe die Methode InvalidateVisual() gefunden, sie löst das erneute Rendern aus. Danke! Du solltest trotzdem deine Antwort posten, um sie als korrekt zu kennzeichnen.