Suchen Sie nach Erklärungen für das WPF Grid ColumnSpan-Verhalten

8

Ich habe eine Frage gestellt Ссылка , aber immer noch fehlt eine gute Erklärung für ein seltsames Verhalten.

Das Ausführen des folgenden XAML zeigt, dass der TextBlock in Spalte 0 Breite größer als 100 ist, obwohl die Spalte auf Breite 100 festgelegt ist. Ich denke, dass die Fremdheit etwas damit zu tun haben kann, dass es in einem ScrollViewer verpackt ist, aber ich nicht Ich weiß nicht warum. Wenn ich eine MaxWidth für die Spalten festlege, funktioniert es gut, aber die Einstellung Width nicht.

  1. Warum wird die Breite von Spalte 0 nicht berücksichtigt?
  2. Warum verhält sich die Spaltengröße beim Entfernen des Scroll-Viewers anders?

Ich schätze jede Erklärung! Das ist ein echtes Rätsel für mich.

%Vor%     
Dale Barnard 15.04.2011, 15:33
quelle

4 Antworten

6

Das ist eine sehr gute Frage und testet die Grenzen unserer Intuition. Es zeigt die Implementierungsdetails der Layout-Logik des Grids.

Die Breite von 100 wird nicht berücksichtigt, weil:

  1. In der dritten Spalte gibt es nichts, was dazu führt, dass das Gitter die Breite erhält.
  2. Der lange Text in der zweiten Zeile ist breiter als in die ersten beiden Spalten passen kann.
  3. Wenn die Breite des Rasters nicht beschränkt oder durch das Elterngitter festgelegt ist, streckt seine Layout-Logik offensichtlich die erste Spalte statt der letzten Spalte.

Wenn Sie eine MaxWidth auf die erste Spalte setzen, beschränken Sie die Layout-Logik des Rasters, sodass sie zur zweiten Spalte weitergeht und diese streckt. Sie werden bemerken, dass es in diesem Szenario breiter als 100 ist.

Sobald jedoch die Breite des Gitters auf einen bestimmten Wert eingestellt ist oder durch sein Elternteil eingeschränkt ist (z. B. wenn kein ScrollViewer im Fenster vorhanden ist), hat die Gitterbreite einen bestimmten Wert, und die dritte Spalte erhält eine gerade Breite obwohl es leer ist. Jetzt ist der automatische Größencode des Rasters deaktiviert und dehnt keine Spalten mehr aus, um zu versuchen, diesen Text einzuquetschen. Sie können dies sehen, indem Sie dem Grid eine bestimmte Breite zuweisen, obwohl es sich immer noch im ScrollViewer befindet.

Bearbeiten: Jetzt, da ich die Antwort der MSDN-Unterstützung in Ihrem ursprünglichen Thread gelesen habe, glaube ich, dass sie korrekt ist, was bedeutet, dass dies wahrscheinlich auf die Implementierung der angehängten Eigenschaft und nicht des Rasters zurückzuführen ist selbst. Allerdings ist das Prinzip das gleiche, und hoffentlich ist meine Erklärung klar genug, um die Subtilität hier zu verstehen.

    
Jerry Bullard 15.04.2011 17:50
quelle
3

Kurze Antwort:
Es ist wegen der Kombination von:
1. Anwesenheit von ScrollViewer, der Gitter (wenn es gewünscht wird) kann jede gewünschte Größe nehmen.
2. Das Gitter hat keine explizite Breite.
3. Eine Spalte (Spalte 2), deren Breite nicht angegeben wurde, die sie auf 1 * setzt, wobei ihre endgültige Größe abhängig von der Größe des Rasters und anderer Spalten bleibt.
4. TextBlock mit Colspan über drei Spalten.

Wenn Sie:
1. Entferne den Scrollviewer, das Gitter darf nur bis zum Client-Bereich des Fensters wachsen (was in deinem Beispiel etwa 278 beträgt), und der lange Textblock muss in diese Breite passen, ansonsten wird er getrimmt.
2. Legen Sie die explizite Breite des Rasters fest, wodurch der Textblock wieder passend zugeschnitten wird.
3. Legen Sie die explizite Breite von Spalte 2 fest, die dem Raster eine feste Breite bietet (100 + 100 + width_of_col2), wodurch der Textblock wieder passend zugeschnitten wird.
4. Entfernen Sie den Spaltenbereich, die Spalten, die ihn nicht enthalten und die feste Breite definiert haben, werden diese Breite annehmen.

Hier ist was passiert:
Dies ist eine grobe und nicht genaue Erklärung der Messen und Anordnen von Pässen , jedoch sollte es eine geben faire Idee.

Am Anfang ist col0 glücklich mit 100, col1 mit 100 und col2 mit 0. Basierend auf dieser Gittergröße wäre 100 + 100 + 0 = 200. Wenn Grid seine zu messenden Kinder (Textblöcke) anfordert, sieht es, dass die ersten zwei Textblöcke in die Breite ihrer Spalten passen. Der dritte Textblock benötigt jedoch 288. Da Grid keine Breite definiert und sich innerhalb eines Scrollviewers befindet, kann es seine Größe erhöhen, wenn es von einem Kind benötigt wird. Das Gitter muss nun seine Größe von 200 auf 288 (d. H. Um 88) erhöhen. Dies bedeutet, dass jede Spalte, auf die sich der Textblock erstreckt (alle drei), um 88/3 ~ = 29 Pixel erweitert wird. Dies macht col0 = 100 + 29 = 129, col1 = 100 + 29 = 129, col2 = 0 + 29.

Versuchen Sie Folgendes:
Fügen Sie ein Rechteck ein, fügen Sie es in col2 ein und legen Sie die Breite des Rechtecks ​​auf 20 fest.

Das ist was passiert:
Beginnen mit col0 und col1 sind glücklich mit jeweils 100, da ihre individuellen Textblöcke weniger brauchen. col2 ist glücklich mit 20, da das Rechteck es braucht. Basierend auf dieser Gitterbreite wäre 100 + 100 + 20 = 220. Wegen des spaltenübergreifenden Textblocks muss das Gitter jedoch seine Größe von 220 auf 288 (d. H. Um 68) erhöhen. Dies bedeutet, dass jede Spalte, auf die sich der Textblock erstreckt (alle drei), um 68/3 ~ = 23 Pixel erweitert wird. Dies macht col0 = 100 + 23 = 123, col1 = 100 + 23 = 123, col2 = 20 + 23 = 43.

HTH.

    
publicgk 15.04.2011 18:23
quelle
2

Hier ist ein weiteres Beispiel, das das Problem mit Canvas anstelle von ScrollViewer zeigt:

%Vor%

Dieses Beispiel zeigt, dass bei unbegrenztem Speicherplatz die ersten beiden Spalten fälschlicherweise um 33% erweitert werden. Ich habe keine funktionierende Referenzquelle, um dies jetzt zu debuggen, weil SP1 die Referenzquelle von .NET4 gebrochen hat, aber ehrlich gesagt, es wird dir nicht helfen, diese Zeile an die Zeile in der Quelldatei anzubringen, also lass uns diese Route nicht gehen.

Stattdessen stimmen wir zu, dass dies definitiv ein Fehler ist und wir können beweisen, dass es ein Fehler ist, indem wir Grid.MaxWidth auf progressiv größere Werte setzen und die Breite von zwei Spalten auf 100 bleibt, egal wie groß sie wird. Aber wenn Sie Grid.MaxWidth unset belassen und die Grid innerhalb einer Canvas setzen, dann ist der Wert während der Messung double.PositiveInfinity und dieser Wert mit einer Spaltenbreite von 133. Als Ergebnis können wir spekulieren, dass einige der Der Sonderfall einer Größenbeschränkung von positiver Unendlichkeit wird während der Berechnung der Spaltengröße nicht korrekt behandelt.

Glücklicherweise bietet dasselbe Experiment eine einfache Umgehungslösung: Geben Sie einfach einen absurd großen Wert für Grid.MaxWidth ein, wenn Grid in einem anderen Steuerelement verwendet wird, das unbegrenzten Speicherplatz zulässt, z. B. ScrollViewer oder Canvas . . Ich empfehle etwas wie:

%Vor%

Dieser Ansatz vermeidet den Fehler, indem er verhindert, dass die Größenbeschränkung den Probematikwert von positiver Unendlichkeit aufweist, während er praktisch den gleichen Effekt erzielt.

Aber das:

%Vor%

löst den Fehler aus.

    
Rick Sladkey 27.04.2011 05:07
quelle
0

Ich habe dieses Problem als Fehler gemeldet:

Ссылка

Bitte stimmen Sie bei diesem Link ab, wenn Sie zustimmen, dass es sich um einen Fehler handelt.

    
Dale Barnard 28.04.2011 14:03
quelle

Tags und Links