<DockPanel>
<TextBox Text="{Binding StringValue}" Name="txtValue" Width="150" Height="21" DockPanel.Dock="Top" Margin="10"></TextBox>
<TextBlock Name="txtResult" DockPanel.Dock="Top" HorizontalAlignment="Center"/>
</DockPanel>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
this.DataContext = new TestClass() { StringValue = "Initial Value" };
txtValue.Text = String.Empty;
if (txtValue.Text == String.Empty)
txtResult.Text = "Hat geklappt";
}
}
public class TestClass : INotifyPropertyChanged
{
private string _StringValue;
public string StringValue
{
get { return _StringValue; }
set
{
_StringValue = value;
OnPropertyChanged("StringValue");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
Ich will (aus verschiedenen komplexeren Gründen) den angezeigten Text ändern. Wie schaff ich es, dass der tatsächlich angezeigte Text im GUI erscheint? Siehe Screenshot
Ich muss ganz ehrlich gestehen, ich werd aus deiner Fragestellung nicht schlau, ich weiß nicht was du willst 🤔
Aber versuch mal bei der TextBox das Binding zu erweitern.
<TextBox Text="{Binding Path=StringValue, Mode=TwoWay}"/>
Dadurch erreichst du, dass die Bindung in beide Richtung (GUI -> Code, Code -> GUI) funktioniert. Falls du das nicht tust, wird der Text (die Property "StringValue"), falls er im Code geändert wurde, nicht in die TextBox übernommen.
Ich hoffe das ist was du wolltest 🙂
du bindest zuerst und weist dann ein neuen wert zu
this.DataContext = new TestClass() { StringValue = "Initial Value" };
txtValue.Text = String.Empty;
das ist kaese
wenn du schon ein binding hast, dann aender den text in der ensprechenden klasse
public TestClass TextBoxText { get; set; }
ctor()
{
TextBoxText = new TestClass() { StringValue = "Initial Value" };
txtValue.DataContext = TextBoxText;
TextBoxText .StringValue = string.Empty;
}
<TextBox Text="{Binding StringValue}" Name="txtValue" Width="150" Height="21" DockPanel.Dock="Top" Margin="10" />
gerade der hauptsinn des bindings ist es ja das man die textbox selber nicht mehr anspricht sondern nur noch mit dem gebundenen objekt kommuniziert
hm, muss wohl doch etwas weiter ausholen:
Ich hab in meiner Klasse auch eine ID drinnen. Die ist vom Typ "int". Beim erstellen eines neuen Objekts kriegt die ID den Wert int.MaxValue (int? vewende ich nicht, da die ID eigentlich kein null haben darf, konzeptionelle Entscheidung). Nun habe ich eine Form in der ich ein Objekt dieses Typs anzeige, auch die ID, die natürlich Disabled ist, und das natürlich über das normale Binding auf "Text". Jetzt steht dann aber in der TextBox der Wert von int.MaxValue drinnen, was natürlich total bescheuert ausschaut.
Ich möchte nun einfach den Text in der TextBox ändern.
Ich hab dafür in WinForms eine NumericTextBox gebastelt, die das alles kontrolliert hat, in der WPF funktioniert das aber nicht mehr, weil sich der angezeigte Text einfach nicht ändert.
Klar ich könnte prüfen ob das ein neues Objekt ist und dann eben nicht binden und einfach "" anzeigen, ich will aber, dass meine TextBox-Klasse das selbst schaff. Aber wenn ich den angezeigten Text nicht beeinflussen kann, schaff ichs einfach nicht.
wenn ich dich richtig verstehe
du meinst bisher steht da
"int.MaxValue"
aber du moechtest eine tatsaechlichen wert anzeigen lassen ?
daufer kannst du dir n converter schreiben - duerfte leicht sein
wenn ich dich richtig verstehe
du meinst bisher steht da
"int.MaxValue"
aber du moechtest eine tatsaechlichen wert anzeigen lassen ?daufer kannst du dir n converter schreiben - duerfte leicht sein
Nein, da ich ja einfach nur die Int-Property auf die TextBox binde steht da natürlich dann "2147483647" drinnen, ich will aber, dass wenn der Wert (also int.MaxValue) gebunden wird, gar nix drinnen steht, das Binding aber trotzdem aktiv ist, weil ich ja, sobald die ID durchs Speichern einen Wert bekommt, den auch gleich anzeigen will (da die gebundene Klasse INotifyPropertyChanged implementiert sollte das gehen)
ah verstehe
fuer den fall bietet sich auch ein converter an
hier mal pseudo:
public sealed class IntegerToTextConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int integerValue = (int)value;
return (integerValue == int.MaxValue) ? "" : integerValue.ToString();
}
public object ConvertBack(object obj, System.Type type, object obj2, CultureInfo info)
{
int integerValue;
if (int.TryParse((string)obj, out integerValue))
return integerValue;
throw new NotSupportedException("The value is not an integer"); // entweder exception oder einfach 0 als return
}
}
<Window...>
<Window.Resources>
<c:IntegerToTextConverter x:Key="intToTextConverter" />
</Window.Resources>
<TextBox Text="{Binding StringValue, Converter={StaticResource intToTextConverter}}" ... />
</Window>
Besten Dank das funktioniert so mal.
Ich verwende für solche Sachen nun ein eigenes Control "MyTextBox". Kann ich den Converter dort irgendwie per Default immer draufgeben, sodass ich beim Binding den Converter nicht extra angeben muss?
Also so, dass ich wieder:
<MyTextBox Text="{Binding StringValue}" ... />
schreiben kann?
du koenntest im ctor des objektes Text binden und fuer das binding den path mit FindResorce setzen
wenn du dann aber Text nochmal in der xaml bindest ueberschreibst du das wieder (da dann ein neues binding objekt erstellt wird)
also laesst sich sagen - ne - da wuesst ich nichts