WPF: Wenn der Inhalt zweier Textblöcke identisch ist, dann sollen die Textblöcke nichts anzeigen
-
Hallo,
ich brauche eure Hilfe. Meine Googlesuche liefert nicht annähernd das, was ich brauche. Dabei brauche ich nichteinmal viel. Es gibt zwei TextBlocks:
<TextBlock Grid.Row="0" Text="{Binding Text1}" /> <TextBlock Grid.Row="1" Text="{Binding Text2}" />
Im Code-behind:
public string Text1 { get { return (string)GetValue(Text1Property); } set { SetValue(Text1Property, value); } } public string Text2 { get { return (string)GetValue(Text2Property); } set { SetValue(Text2Property, value); } }
Soweit alles ok. Die zwei Textblöcke sind dazu da, zwei Strings anzuzeigen, damit der Benutzer die Inhalte vergleichen kann. Was ich machen will: wenn die Inhalte der beiden Textblöcke identisch sind, dann sollen die Textblöcke nichts anzeigen, um den Benutzer zu entlasten (der Benutzer weiss dann, dass die Inhalte identisch sind).
Wie stelle ich das in XAML an?
-
endline schrieb:
Wie stelle ich das in XAML an?
Mach eine bool-Property die den Status hält, und binde an die Visible-Eigenschaft der beiden Textblöcke (Dazu kannst du z.B. den BooleanToVisibilityConverter verwenden; Ein Beispiel ist in den Kommentaren verlinkt).
-
Danke, das funktioniert soweit. Wenn die Elemente versteckt werden, wird mein Layout verhunzt.
Ich würde gerne einfach nur die TextBlock.Text-Property auf string.Empty setzen.
-
endline schrieb:
Danke, das funktioniert soweit. Wenn die Elemente versteckt werden, wird mein Layout verhunzt.
Ich würde gerne einfach nur die TextBlock.Text-Property auf string.Empty setzen.
Dann Schreibe entweder einen eigenen Converter (der bei false nicht Collapse sondern Hide [oder wie es auch immer heißt] setzt), oder Wrappe deine Textproperties für die Anzeige so, das sie einen Leerstring in diesem Fall zurückgeben.
-
asc schrieb:
endline schrieb:
Danke, das funktioniert soweit. Wenn die Elemente versteckt werden, wird mein Layout verhunzt.
Ich würde gerne einfach nur die TextBlock.Text-Property auf string.Empty setzen.
Dann Schreibe entweder einen eigenen Converter (der bei false nicht Collapse sondern Hide [oder wie es auch immer heißt] setzt),
Hidden und Collapse haben hier den selben Effekt. Für das Layout 'verschwindet' der TextBlock und meine Border schrumpfen etc.
oder Wrappe deine Textproperties für die Anzeige so, das sie einen Leerstring in diesem Fall zurückgeben.
Ich habe herausgefunden, dass man in WPF ausser GetValue und SetValue keine weitere Logik in die Wrapper-Property einbauen darf, weil die Werte der DependencyProperty nicht immer über die Wrapper gesetzt oder gelesen werden.
Ich habe jetzt das hier testweise nur für einen TextBlock versucht:
<TextBlock Grid.Row="0" Text="{Binding Text1}"> <TextBlock.Resources> <Style TargetType="{x:Type TextBlock}"> <Style.Triggers> <DataTrigger Binding="{Binding IsIdentical}" Value="True"> <Setter Property="Background" Value="Red"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Resources> </TextBlock> // Gesamter C#-Code: public static readonly DependencyProperty Text1Property = DependencyProperty.Register("Text1", typeof(String), typeof(CmpTexts)); public static readonly DependencyProperty Text2Property = DependencyProperty.Register("Text2", typeof(String), typeof(CmpTexts)); public string Text1 { get { return (string)GetValue(Text1Property); } set { SetValue(Text1Property, value); } } public string Text2 { get { return (string)GetValue(Text2Property); } set { SetValue(Text2Property, value); } } public bool IsIdentical { get { return Text2 == Text1; } }
Das Ergebnis: Alle TextBlöcke werden rot, obwohl es Werte gibt die nicht identisch sind. Ich kann nur vermuten, dass zum Zeitpunkt des Aufrufes von 'IsIdentical' in Text1 & Text2 nicht die tatsächlichen Werte drinstehen, sondern vielleicht irgendein Defaultwert (NULL?) und der Rückgabewert deshalb immer TRUE ist und deshalb alles rot wird. WPF-GUI lässt sich soweit ich das beurteilen kann absolut gar nicht debuggen.
Edit: Ich glaube, dass wenn die GUI aufgebaut wird, erst das Binding zu 'IsIdentical' ausgewertet wird (und das Rückgabeergebnis immer TRUE ist, da dort NULL==NULL verglichen wird), und erst im Anschluss erhalten die Properties 'Text1' & 'Text2' ihre Werte. Die Reihenfolge ist hier verkehrt...
-
endline schrieb:
Hidden und Collapse haben hier den selben Effekt.
Wundert mich, da die MSDN eigentlich etwas anderes andeutet (Hidden sollte eigentlich den Platz reservieren, als wäre das Control sichtbar).
-
Ebenfalls eine Möglichkeit wäre ein MultiBinding mit einem
IMultiValueConverter
. An beide Textboxen bindest jeweils du die beiden Eigenschaften in umgekehrter Reihenfolge. BeiConvert
prüfst du, ob die beiden gleich sind und gibstString.Empty
zurück und sonst den ersten Wert. BeiConvertBack
setzt du den zweiten Wert aufBinding.DoNothing
.Zu deiner aktuellen Lösung: Prüf halt in
IsIdentical
auch noch aufnull
und sag dann, dass die Wert nicht identisch sind. Zudem musst du natürlich noch einPropertyChanged
Event auslösen, dassIsIdentical
sich geändert hat. Am besten hängst du dich dazu in die beidenDependencyProperty
Text1
undText2
rein und verwendest denPropertyChangedCallback
.Zudem sollte eben Hidden nichts verändern, wenn du alles richtig gemacht hast
Grüssli
-
Dravere schrieb:
Ebenfalls eine Möglichkeit wäre ein MultiBinding mit einem
IMultiValueConverter
. An beide Textboxen bindest jeweils du die beiden Eigenschaften in umgekehrter Reihenfolge. BeiConvert
prüfst du, ob die beiden gleich sind und gibstString.Empty
zurück und sonst den ersten Wert. BeiConvertBack
setzt du den zweiten Wert aufBinding.DoNothing
.Zu deiner aktuellen Lösung: Prüf halt in
IsIdentical
auch noch aufnull
und sag dann, dass die Wert nicht identisch sind. Zudem musst du natürlich noch einPropertyChanged
Event auslösen, dassIsIdentical
sich geändert hat. Am besten hängst du dich dazu in die beidenDependencyProperty
Text1
undText2
rein und verwendest denPropertyChangedCallback
.Zudem sollte eben Hidden nichts verändern, wenn du alles richtig gemacht hast
Grüssli
Danke Dravere. So hab ich's gemacht und es funktioniert.