Wie funktioniert scrollviewer, wenn die Höhe in WPF auf Auto gesetzt ist?

7

Ich habe gelernt, dass die vertikale Bildlaufleiste nicht wirksam wird, wenn die Höhe einer Rasterzeile, in der ScrollViewer liegt, als Auto festgelegt wird, da die tatsächliche Größe von ScrollViewer größer als sein kann die Höhe in Sicht. Damit die Bildlaufleiste funktioniert, sollte die Höhe entweder auf eine feste Zahl oder auf eine Sternhöhe eingestellt sein.

Allerdings habe ich jetzt diese Anforderung, dass ich zwei verschiedene Ansichten in zwei Rasterzeilen habe, und ich habe eine Umschalttaste, um zwischen diesen beiden Ansichten zu wechseln: Wenn eine Ansicht angezeigt wird, ist die andere ausgeblendet / verschwunden. Also habe ich zwei Zeilen definiert, beide Höhen werden als Auto gesetzt. Und ich verbinde die Sichtbarkeit der Ansicht in jeder Zeile mit einer booleschen Eigenschaft aus meinem ViewModel (eine wird von True nach Visible konvertiert und die andere von True nach Collapsed . Die Idee ist, wenn die Sichtbarkeit einer Ansicht ist Collapsed , die Höhe der Rasterzeile / Ansicht wird automatisch auf 0 geändert.

Die Ansicht show / hidden funktioniert einwandfrei. In einer Ansicht habe ich jedoch eine ScrollViewer , was, wie ich bereits erwähnt habe, nicht funktioniert, wenn die Zeilenhöhe auf Auto gesetzt ist. Kann mir jemand sagen, wie ich diese Anforderung erfüllen kann, während das ScrollViewer automatisch funktioniert? Ich schätze, ich kann die Höhe in Code-Behind einstellen. Aber da ich MVVM verwende, würde es zusätzliche Kommunikation / Benachrichtigung erfordern. Gibt es einen einfacheren Weg, das zu tun?

    
tete 14.10.2013, 08:02
quelle

3 Antworten

6

Ändere die Höhe von Auto auf * , wenn du kannst.

Beispiel:

%Vor%     
Maciek Ś. 14.10.2013, 08:43
quelle
15

In MVVM war die Methode, die für mich funktionierte, darin, die Höhe von ScrollViewer an die ActualHeight des übergeordneten Steuerelements zu binden (das immer vom Typ UIElement ist).

ActualHeight ist eine schreibgeschützte Eigenschaft, die erst nach dem Zeichnen des Steuerelements auf dem Bildschirm festgelegt wird. Es kann sich ändern, wenn das Fenster in der Größe geändert wird.

%Vor%

Aber was, wenn das übergeordnete Steuerelement eine unendliche Höhe hat?

Wenn das übergeordnete Steuerelement eine unendliche Höhe hat, haben wir ein größeres Problem. Wir müssen die Höhe aller Eltern einstellen, bis wir ein Steuerelement mit einer nicht-unendlichen Höhe treffen.

Snoop ist absolut unschätzbar dafür:

Wenn die "Höhe" für ein beliebiges XAML-Element 0 oder NaN ist, können Sie es auf einen der folgenden Werte setzen:

  • Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UIElement}}"
  • VerticalAlignment="Stretch"
  • Height="Auto"

Hinweis: Verwenden Sie VerticalAlignment="Stretch" , wenn Sie ein Kind von Grid mit einem <RowDefinition Height="*"> sind, und% Binding RelativeSource... , wenn das nicht funktioniert.

Wenn Sie interessiert sind, hier sind alle meine früheren Versuche, dieses Problem zu beheben:

Anhang A: Vorheriger Versuch 1

Kann dies auch verwenden:

%Vor%

Anhang B: Vorheriger Versuch 2

Nützliche Informationen: Siehe WPF - Auto-Höhe in Kombination mit MaxHeight .

Wenn nichts zu funktionieren scheint, liegt es wahrscheinlich daran, dass ActualHeight des Elternteils entweder 0 (also nichts ist sichtbar) oder sehr groß ist (der scrollviewer muss also nie erscheinen). Dies ist eher ein Problem, wenn tief verschachtelte Grids vorhanden sind, mit einem Scrollviewer ganz unten.

  • Verwenden Sie Snoop, um ActualHeight des übergeordneten StackPanel zu finden. Filtern Sie in Eigenschaften nach dem Wort "Actual" , wodurch ActualHeight und ActualWidth zurückgegeben werden.
  • Wenn ActualHeight null ist, geben Sie ihm eine minimale Höhe mit MinHeight , damit wir wenigstens etwas sehen können.
  • Wenn ActualHeight so groß ist, dass es über den Rand des Bildschirms hinausgeht (d. h. 16.000), geben Sie ihm mit MaxHeight eine angemessene maximale Höhe, sodass die Bildlaufleisten angezeigt werden.

Sobald die Bildlaufleisten erscheinen, können wir sie weiter bereinigen:

  • Binden Sie Height von StackPanel oder Grid an ActualHeight des übergeordneten Elements.

Fügen Sie schließlich ein ScrollViewer in dieses StackPanel ein.

Anhang C: Vorheriger Versuch 3

Es stellt sich heraus, dass dies manchmal fehlschlagen kann:

%Vor%

Der Grund? Wenn die Bindung fehlschlägt, wird die Höhe Null und nichts wird gesehen. Die Bindung kann fehlschlagen, wenn wir an ein Element gebunden sind, auf das nicht zugegriffen werden kann. Die Bindung schlägt fehl, wenn wir up in den visuellen Baum und dann down in einen Blattknoten (z. B. bis zum übergeordneten Gitter und dann bis zum ActualHeight einer an das Gitter angehängten Zeile) gehen. Deshalb funktioniert die Bindung an ActualWidth von RowDefinition einfach nicht.

Anhang D: Vorheriger Versuch 4

Am Ende habe ich das geschafft, indem ich sicherstellte, dass Height=Auto für alle übergeordneten Elemente von uns bis zum ersten <Grid> -Element im UserControl funktioniert.

    
Contango 04.09.2014 10:43
quelle
0

Sie können entweder eine feste Höhe auf Ihrem ScrollViewer setzen, aber dann müssen Sie berücksichtigen, dass die zweite Zeile Ihres Rasters diese Höhe haben wird, da das erste Kind der Zeile der ScrollViewer ist und die Höhe der Zeile automatisch ist oder Sie die Höhe binden von ScrollViewer zu einem anderen Steuerelement in Ihrem Layout. Wir wissen nicht, wie Ihr Layout aussieht.

Am Ende, wenn Sie beide nicht mögen, setzen Sie einfach die Höhe der Zeile auf * wie swiszcz vorgeschlagen oder hack wpf schreiben Sie Ihr eigenes benutzerdefiniertes Panel, das in der Lage sein wird, alles Mögliche in jedem Paralleluniversum oder etwas Ähnliches zu gestalten. :)

    
dev hedgehog 14.10.2013 08:46
quelle

Tags und Links