mayho33
Goto Top

C-Sharp WPF Binding und Rechnen mit Element.With

Hi @ All

Eventuell geht es dem einen oder anderen ähnlich wie mir: WPF ist mächtig, hat aber seine Tücken und ich stolpere regelmäßig darüber. Zumindest für ein Problem, das Subtrahieren / Addieren mehrere Width / Height-Properties, habe ich nun eine einfache Lösung gefunden und ich möchte meine Erkenntnis gerne mit euch teilen. Vielleicht hilft es so manchem die lange Suche etwas zu verkürzen.

Im Netz finden sich viele Anleitungen via IValueConverter oder IMultiValueConverter zu rechnen, mir persönlich sind viele davon aber viel zu aufwändig für so einen mickrigen Effekt (siehe z.B:. hier: http://stackoverflow.com/questions/4969600/how-do-you-change-a-bound-va ... oder hier: http://www.ikriv.com/dev/wpf/MathConverter/index.shtml).

Die simple Lösung:

Angenommen in einem DockPanel gibt es 3 Controls. 1) TextBox, 2) Separator, 3) Button.
Separator und Button haben eine feste Breite, TextBox.Width soll aber auf MainWindow.Width gebunden sein damit A) die Textbox ohne Text gleich eine bestimmte Breite hat, B) man sich das manuelle Ausrechnen (TextBox.Width = ( Separator.Width + Button.Width)) sparen kann. Viel Arbeit wenn es mehrere solche Konstellationen gibt und sich zufällig Width oder Height des MainWindow ändert.

Was habe ich also gemacht? Zuerst im Xaml jedem Element einen x:Name geben:

<DockPanel x:Name="pathDock"  
                       Height="25"  
                       LastChildFill="True">  
                <TextBox x:Name="textBox_Path"  
                                 Width="{Binding Path=PathTextBoxWidth}"  
                                 Height="{Binding ElementName=pathDock, Path=ActualHeight}"  
                                 HorizontalAlignment="Left"  
                                 VerticalAlignment="Top"  
                                Text="{Binding Path=FolderPath, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
                                TextWrapping="NoWrap" />  
                <Separator x:Name="pathSeparator"  
                                    Width="5"  
                                    Background="Transparent" />  
                <Button x:Name="button_Path"  
                              Width="35"  
                              Height="{Binding ElementName=pathDock, Path=ActualHeight}"  
                             HorizontalAlignment="Left"  
                             VerticalAlignment="Top"  
                            Click="button_Path_Click"  
                            Content=". . ." />  
            </DockPanel>

Dann irgendwo ein Property erstellt, welches die Differenz für mich ausrechnet und dieses Property auf TextBox.Width gebunden
public double PathTextBoxWidth
        {
            get
            {
                double wDock = pathDock.ActualWidth;
                double wSep = pathSeparator.ActualWidth;
                double wButton = button_Path.ActualWidth;
                return wDock - (wSep + wButton);
            }
        }

Voila! Kein Rechnen mehr und die Breite passt auch. Für mich hat es einen ungemeinen Mehrwert, erspart mir eine Menge an Zeit und ist auch nach Monaten noch leicht nachvollziehbar. Ich hoffe der eine oder andere denkt genauso.


Grüße!

Mayho

Content-ID: 334984

Url: https://administrator.de/knowledge/c-sharp-wpf-binding-und-rechnen-mit-element-with-334984.html

Ausgedruckt am: 30.12.2024 um 17:12 Uhr

H41mSh1C0R
H41mSh1C0R 13.04.2017 um 05:34:35 Uhr
Goto Top
Servus,

schicke Lösung, aber gibts für sowas nicht das Docking ansich? Die Elemente jeweils so verankern das die Größe automatisch passt.

VG
132895
132895 13.04.2017 um 11:07:57 Uhr
Goto Top
mayho33
mayho33 14.04.2017 aktualisiert um 13:19:19 Uhr
Goto Top
@elchapo
Dein Beispiel spielt mit Buttons. Ganz anderes Verhalten. Spiel es mal Mit Textboxes durch. Die TextBox soll schon bevor sie befüllt wird die volle Breite haben. Das könnte man erzielen indem man Textbox.Width = "<double>" angibt, was aber bedeutet, dass man alle Width-Properties ändern muss, wenn sie Width von Parent ändert.

@H41mSh1C0R
Leider passt sich die Breite aber nur an den enthaltenen Text an. Wenn text.Lenght = 0 ist ist Textbox.Width auch 0. Egal ob gedockt oder nicht. Zumindest beobachte ich das genau so bei textBoxes.

Im Grunde ist es ein Design-Problem. Entweder gibt man einer TextBox eine fixe Breite oder lässt sie dynamisch mitwachsen. Schaut halt nicht sehr schmucke aus, wenn alle Textboxen nur 3 mm breit sind, weil sie erst befüllt sein müssen, oder unterschiedlich breit sind, weil die text.Lenght unterschiedlich ist.

Hast aber schon recht.
132895
132895 14.04.2017 aktualisiert um 13:20:53 Uhr
Goto Top
Zitat von @mayho33:

@elchapo
Dein Beispiel zeigt genau den Effekt den ich nicht will. Die TextBox soll schon bevor sie befüllt wird die volle Breite haben. Das könnte man erzielen indem man Textbox.Width = "<double>" angibt, was aber bedeutet, dass man alle Width-Properties ändern muss, wenn sie Width von Parent ändert.
Bei mir füllt sie sich automatisch mit dem Platz der frei ist auch ohne Text ;-P
mayho33
mayho33 14.04.2017 aktualisiert um 13:43:36 Uhr
Goto Top
Habe es nun nochmal in einem Test nach gebastelt. Plötzlich funktionierts!
Dafür gibts Punkte face-smile. Funkt aber nur im Test. In meinem eigentlichen Projekt hauts so nicht hin. Muss ich mich wohl auf Fehlersuche begeben.

EDIT

Fehler gefunden! Dummes VisualStudio hat mir ganz hinten bei einigen TextBoxes ein Margin eingepflanzt als ich zusätzliche Rows und Columns einbaut habe. Wie bescheuert!
H41mSh1C0R
H41mSh1C0R 14.04.2017 um 16:44:45 Uhr
Goto Top
=)

Wollt gerade schreiben "Bei mir geht". *gg*
132895
132895 14.04.2017 um 17:36:13 Uhr
Goto Top
Zitat von @mayho33:
Dafür gibts Punkte face-smile.
Nee Eier face-smile.
... Muss ich mich wohl auf Fehlersuche begeben.
Faule Eier sucht man erst nach Ostern face-wink
Fehler gefunden! Dummes VisualStudio hat mir ganz hinten bei einigen TextBoxes ein Margin eingepflanzt als ich zusätzliche Rows und Columns einbaut habe. Wie bescheuert!
Na dann hat VS das Wochenende Stubenarest ...
H41mSh1C0R
H41mSh1C0R 20.04.2017 um 07:26:36 Uhr
Goto Top
Deine Frage scheint geklärt zu sein, bitte noch auf "gelöst" setzen, danke.
132895
132895 20.04.2017 um 07:34:51 Uhr
Goto Top
Zitat von @H41mSh1C0R:

Deine Frage scheint geklärt zu sein, bitte noch auf "gelöst" setzen, danke.
Bei einem Tipp?
H41mSh1C0R
H41mSh1C0R 20.04.2017 um 08:10:32 Uhr
Goto Top
Doch zu wenig geschlafen. *ggg*

/ignore ^^