Laden...

TextBox.Text ändern nach Binding

Erstellt von tkrasinger vor 14 Jahren Letzter Beitrag vor 14 Jahren 8.871 Views
T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren
TextBox.Text ändern nach Binding
<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

N
85 Beiträge seit 2007
vor 14 Jahren

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 🙂

U
1.578 Beiträge seit 2009
vor 14 Jahren

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

T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren

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.

U
1.578 Beiträge seit 2009
vor 14 Jahren

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

T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren

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)

U
1.578 Beiträge seit 2009
vor 14 Jahren

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>
T
tkrasinger Themenstarter:in
574 Beiträge seit 2008
vor 14 Jahren

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?

U
1.578 Beiträge seit 2009
vor 14 Jahren

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