[WPF] ProgressBar + GridSplitter, ProgressBar wird grösser aber nicht mehr kleiner
-
Hier der XAML Code:
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ListBox Grid.Column="0" HorizontalContentAlignment="Stretch"> <ListBox.ItemTemplate> <DataTemplate> <DockPanel> <TextBlock DockPanel.Dock="Left" Text="{Binding}" /> <ProgressBar Margin="5,3,5,3" Value="67" /> </DockPanel> </DataTemplate> </ListBox.ItemTemplate> test </ListBox> <GridSplitter Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="3" /> <TextBox Grid.Column="2"> Hello World! How are you? </TextBox> </Grid>
Wenn ich den GridSplitter nach rechts bewege, dann wird die TextBox kleiner und die ProgressBar grösser. Alles wie gewünscht. Wenn ich den GridSplitter dann wieder auf die Anfangsposition schiebe, geht die ProgressBar nicht wieder auf ihre ursprüngliche Grösse zurück, sondern bleibt etwas grösser, wodurch in der ListBox ein horizontaler Scrollbalke erscheint. Wieso?
Grüssli
-
*hust* Sind wir bei schlechten Standardverhalten? - Ich guck greade...
-
Habe ich im anderen Thread gerade beschrieben, das ist kein Fehler sondern völlig normal durch den Measurement prozess
http://www.c-plusplus.net/forum/viewtopic-var-p-is-1901011.html#1901011
CSL schrieb:
Auch verständlich.
Beim Measurement Prozess (OnAllignment & OnMeasure) Wird ermittelt wie breit die Items sein können.
Dort merkt die ListBox "Oh, ich kann Horizontal Scrollen, d.h. ich ich habe als Maximale länge double.PositiveInfinity" dann sagt es den Childs, "Ihr habt so viel platz wie ihr braucht". Und die Childs, also die ListBoxItems nehmen sich dann den Maximalen sichtbaren bereich.
Ist ja klar, sonst wäre es ja unendlich.
Nun Ziehst du es mit dem GridSplitter größer, und die ListBox rendert neu mit dem entsprechenden PositiveInfinity werten.
Nun ziehst du es wieder kleiner und die ListBox merkt: "Oh, es ist kleiner geworden, aber das macht nichts, ich kann ja Horizontal Scrollen".
Also wird es nicht verkleinert sondern eine ScrollBar angezeigt.
Dein Problem kannst du lösen indem du die HorizontalScrollBarVisibility der ListBox auf Disable stellst.Nun wirst du dich fragen warum die ProgressBar nicht verkleinert wird, wenn du dich das fragst fehlt dir scheinbar die Information des Measurement Prozesses.
Jedes Control bekommt von seinem Parent eine Maximal verfügbare Größe, richtet sich selber danach aus und gibt wiederum ihren Childs den verfügbaren Platz den sie einnehmen können.
Da aber das ListBoxItem vom Parent den alten Platz bekommt, gibts nichts zu verkleinern.
Darum sagt die ListBox ihren Childs die selbe Größe wie vorher, da die ListBox ja nun eine ScrollBar hat.Lange rede Kurzer sinn, die ListBox weiß gar nicht das die Horinzontale ScrollBar nicht erwünscht ist, kann ja auch vom User explizit gesetzt sein.
Sobald du die HorizontalScrollBarVisibility deaktiviert hast Passiert folgendes
Die ListBox sagt ihren Childs: "Maximale länge ist meine CurrentWidth"
Die ListBoxItems bekommen das, teilen ihren Platz auf und geben jeden Child ihren verfügbaren bereich. Da es aber kein PositiveInfinity hat wird den Childs ein Maximaler Platz gegeben, und das ist für die ProgressBar kein Problem da sie sich Verkleinern kann.
-
Du musst dir schon mehr Mühe geben
Edit:
- Eine ListBox hat keine Eigenschaft HorizontalScrollBarVisibility
http://img200.imageshack.us/img200/7326/14831255.png
- Initalisierungszustannd
- GirdSplitter wird nach rechts verschiebt. Linke Controls werden vergößert, Rechte Controls werden abgeschnitten. Keine Scrollbars werden angezeigt. Bis jetzt alles ok.
- GridSplittter wird zum vorherige Position verschoben, dabei sieht man, dass die Margins ignoriert werden, Progressbar ist größer als die Grid-Cell und wird abgeschnitten und Scrollbars werden nicht angezeigt.
Die Frage ist, wie kann man nun die Scrollbars abschalten.
-
Meinst du mich? Was willst du mir damit sagen?
Meine Beschreibung ist natürlich nur verkürzt, bei der einteilung des Verfügbaren Platzes werden die Childs natürlich auch gefragt "Wie groß wollt" ihr sein, aber in diesem geschilderten Fall sagt die ScrollBar den alten platz da die ListBoxItems ja auch den alten Platz bekamen.
PS. Mein Edit rührt daher das ich den Erklärungsteil etwas umformulierte, damit es verständlicher ist,
-
@CSL,
Probier den Code bitte zuerst mal aus.Ich mach dir mal eine Bilderreihe. Wir starten:
http://www.dracopien.ch/temp/wpf/state01.pngSchieben den Splitter nach rechts, alles wunderbar:
http://www.dracopien.ch/temp/wpf/state02.pngNun schieben wir den Splitter wieder zurück. Immer noch alles wunderbar!
http://www.dracopien.ch/temp/wpf/state03.pngUnd dann auf einmal, wir die ProgressBar abgeschnitten! Es erscheint noch kein Scrollbalken!
http://www.dracopien.ch/temp/wpf/state04.pngUnd erst wenn wir dann weiter nach links gehen, erscheint endlich der Scrollbalken:
http://www.dracopien.ch/temp/wpf/state05.pngDu willst mir doch nicht sagen, dass du dieses Verhalten als intuitiv ansiehst?
Grüssli
-
Okay, grad ma geschaut.
Die ScrollBar wird angezeigt sobald der bereich in auf dem Value stößt. Das ist tatsächlich ein Bug, siehe http://social.msdn.microsoft.com/forums/en-US/wpf/thread/2fc8c523-21f4-48d6-a06b-12fd76ff5791/
Scheinbar wir der Platzbedarf falsch berechnet.
Das Problem kannst du (Leider nur Teilweise wegen der falschen Berechnung) mit
<ListBox HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
beheben.Ändert aber nichts an meiner vorherigen aussage, das die ScrollBar kommt ist ja normal, der Bug der hier vorliegt ist das diese zu spät kommt, die müsste sofort beim verkleinern erscheinen, nicht erst beim erreichen des Value Punktes.
-
Genau so sieht meine Erfahrung mit WPF aus
Kleinste einfache Dinge und dann geht es nicht, weil WPF nicht geht :pZum Rest kann ich nur sagen: Empfinde ich nicht als intuitiv. Klar ist es logisch mit den gegebenen Standardwerten, aber diese sind definitiv nicht intuitiv. Deshalb muss man zuerst eine Menge an Erfahrung sammeln, bis man alle diese nicht intuitiven Standardwerte kennt und darauf reagieren kann. Sowas hast du eben in WinForms deutlich weniger. WinForms verhält sich deutlich öfter so, wie man es auf anhieb vermuten würde.
Aber naja, dazu können wir im anderen Thread weiterdiskutieren und hat sicher auch eine subjektive Komponente dabei
Grüssli
-
Es "geht" nicht weil ein Bug in der Komponente vor liegt, und das kann man nie ausschließen, auch in Forms nicht. Als Forms noch neuer war, lagen solche Fehler bestimmt auch vor
Es ist wie gesagt nicht unintuitiv sondern einfach nur ein Bug.
-
CSL schrieb:
Es "geht" nicht weil ein Bug in der Komponente vor liegt, und das kann man nie ausschließen, auch in Forms nicht. Als Forms noch neuer war, lagen solche Fehler bestimmt auch vor
Es ist wie gesagt nicht unintuitiv sondern einfach nur ein Bug.Nein, kein Bug, das ist BLÖDSINN!!
-
CSL schrieb:
Es "geht" nicht weil ein Bug in der Komponente vor liegt, und das kann man nie ausschließen, auch in Forms nicht. Als Forms noch neuer war, lagen solche Fehler bestimmt auch vor
Es ist wie gesagt nicht unintuitiv sondern einfach nur ein Bug.Schon klar, ich hätte wohl noch ein Smilie hinmachen sollen
Grüssli
-
Aber ein UI-Lib mit Layout-Manager und Resize-Bugs, ist das seriös?
-
Es ist kein Resize Bug, es ist ein Arrange/Measurement Bug in der ProgressBar Komponente.
In dem Augenblick wenn der DockPanel seine Childs nach die Größe fragt, child.DesiredSize, gibt die ProgressBar scheinbar einen falschen wert, nicht die Eigene Width sondern die Width bis wo Value gezeichnet wird.
-
CSL schrieb:
Es ist kein Resize Bug, es ist ein Arrange/Measurement Bug in der ProgressBar Komponente.
In dem Augenblick wenn der DockPanel seine Childs nach die Größe fragt, child.DesiredSize, gibt die ProgressBar scheinbar einen falschen wert, nicht die Eigene Width sondern die Width bis wo Value gezeichnet wird.Du laberst hochgradigen Dünnschiss!!
-
Dann klär mich auf.
-
CSL schrieb:
Dann klär mich auf.
sinnlos!