none
MVVM Textfeld aktualisieren RRS feed

  • Frage

  • Hallo.

    Ich habe folgendes Problem:

    Ich habe ein Textfeld dessen Namen an die Propertie Ergebnis gebunden ist. 

    Wenn ich nun Ergebnis ändere, wird aber nicht der Wert im Textfeld verändert. Warum nicht? Ich habe 

    INotifyPropertyChanged  eingefügt.

    Gruß Flier

    Montag, 15. Juli 2013 12:47

Antworten

  • Dann hier nochmal die komplette Lösung:
    class ErgebnisViewModel : INotifyPropertyChanged 
    {
        private Model _Model;
        public ErgebnisViewModel()
        {
            _Model = new Model();
            _Ergebnis = _Model.Ergebnis;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected internal void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
        }
    
        private string _Ergebnis;
        public string Ergebnis
        {
            get { return _Ergebnis; }
            set
            {
                if (_Ergebnis == value) return;
                _Ergebnis = value;
                _Model.Ergebnis = value;
                OnPropertyChanged("Ergebnis");
            }
        }
    
        private ICommand zahlcommand;
        public ICommand ZahlCommand
        {
            get 
            {
                if (zahlcommand == null)
                {
                    zahlcommand = new CommandBase((param) => this.doStuff());
                }
                return zahlcommand;
            }
        }
    
        private void doStuff()
        {
            Ergebnis  = "1";          
        }   
    }

    XAML:

    <Grid>
        <TextBox x:Name="Textbox" HorizontalAlignment="Left" Height="23" Margin="188,34,0,0" TextWrapping="Wrap" Text="{Binding Ergebnis}" VerticalAlignment="Top" Width="120"/>
        <Button HorizontalAlignment="Left" Command="{Binding ZahlCommand}" Margin="215,185,0,0"  VerticalAlignment="Top" Width="75">1</Button>
    </Grid>

    • Als Antwort markiert Flier94 Montag, 15. Juli 2013 14:25
    Montag, 15. Juli 2013 14:15

Alle Antworten

  • Hallo Flier,

    die Frage lässt sich mit diesen Informationen nur schwer beantworten. Um welche Plattform handelt es sich? WPF, Windows Phone, Windows RT? Da gibt es durchaus unterschiede bezüglich des Binding-Verhaltens. Bei WindowsPhone musst du zum Beispiel explizit BindingMode auf TwoWay setzen, damit die Änderungen in beide Richtungen funktionieren.

    Kannst du uns den Code schicken, wie du das INotifyPropertyChanged-Interface implementiert hast und wie du das Binding im XAML gesetzt?

    Viele Grüße,
    Thomas Fröhle
    App-Entwickler-Hotline für MSDN Online Deutschland

    Disclaimer:
    Bitte haben Sie Verständnis dafür, dass wir hier auf Rückfragen gar nicht oder nur sehr zeitverzögert antworten können.
    Bitte nutzen Sie für Rückfragen oder neue Fragen den telefonischen Weg über die App-Entwickler-Hotline: http://www.msdn-online.de/Hotline
    MSDN Hotline: Schnelle & kompetente Hilfe für Entwickler: kostenfrei!

    Es gelten für die App-Entwickler-Hotline und dieses Posting diese Nutzungsbedingungen, Hinweise zu MarkenzeichenInformationen zur Datensicherheit sowie die gesonderten Nutzungsbedingungen für die App-Entwickler-Hotline.

    Montag, 15. Juli 2013 12:55
  • Entschuldigung :)

    Das Programm ist in WPF. Alles ist auf MVVM aufgebaut. Hier ist ein Link wo das komplette Programm enthalten ist(Ist mit WinRar Komprimiert worden):

    https://www.dropbox.com/sh/49fd9dg8qy3xeqo/OM0D5kC9CO

    Gruß Flier

    Montag, 15. Juli 2013 13:02
  • Hallo Flier,

    ich habe zwei Fehler in deinem Code gefunden.

    1) Du bindest die Textbox an die Eigenschaft "Name":

    <TextBox ... Text="{Binding Name}" />

    In der Eigenschaft Set-Methode von Name wird aber die Änderung von "Ergebnis" in OnPropertyChanged() ausgerufen:

    private string _Ergebnis;
    public string Name
    {
        get { return _Ergebnis; }
        set
        {
            if (_Ergebnis == value) return;
            _Ergebnis = value;
            OnPropertyChanged("Ergebnis");
        }
    }

    2) In der Methode doStuff() wird die Ergebnis-Eigenschaft des Models gesetzt:

    private void doStuff()
    {
        _Model.Ergebnis = "1";     
    }
    Model implementiert jedoch weder das INotifyPropertyChanged-Interface noch ist die Eigenschaft an die Textbox gebindet.

    Montag, 15. Juli 2013 13:13
  • Hallo Thomas.

    Danke für die schnelle Antwort.

    Ich habe die  Set-Methode von Name  wie folgt verändert:

    private string _Ergebnis;
            public string Name
            {
                get { return _Ergebnis; }
                set
                {
                    if (_Ergebnis == value) return;
                    _Ergebnis = value;
                    OnPropertyChanged("Name");
                }
            }

    Ich hoffe das ist richtig so. Jedoch weis ich nicht was ich an der Methode doStuff() ändern soll. Ich bin leider noch nicht so bewandert auf diesem Gebiet. Was soll ich machen?

    Gruß Flier

    PS:

    Ich dachte das hier ist das INotifyPropertyChanged-Interface

    public event PropertyChangedEventHandler PropertyChanged;
    
            protected internal void OnPropertyChanged(string propertyname)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }


    • Bearbeitet Flier94 Montag, 15. Juli 2013 13:26 Verständnis
    Montag, 15. Juli 2013 13:24
  • Hallo Flier,

    das Interface hast du richtig implementiert. Dies wäre eine funktionierende Implementierung:

    private string _Ergebnis;
    public string Ergebnis
    {
        get { return _Ergebnis; }
        set
        {
            if (_Ergebnis == value) return;
            _Ergebnis = value;
            _Model.Ergebnis = value;
            OnPropertyChanged("Ergebnis");
        }
    }

    und das Binding ändern zu:

    <TextBox ... Text="{Binding Ergebnis}" />

    In der DoStuff()-Methode dann:

    private void doStuff()
    {
        Ergebnis  = "1";          
    }

    Das wäre ein Vorschlag. Es kommt aber auch darauf an, was du genau vorhast.



    Montag, 15. Juli 2013 13:53
  • Hi Thomas.

    Danke für die Antwort!

    Mein Ziel ist es, auf den Button zu drücken und das dann im Textfeld eine 1 erscheint. 

    Aber irgendwie geht es nicht, auch nicht mit deiner Lösung. 

    Gruß Flier


    • Bearbeitet Flier94 Montag, 15. Juli 2013 14:07 Danke
    Montag, 15. Juli 2013 14:03
  • Dann hier nochmal die komplette Lösung:
    class ErgebnisViewModel : INotifyPropertyChanged 
    {
        private Model _Model;
        public ErgebnisViewModel()
        {
            _Model = new Model();
            _Ergebnis = _Model.Ergebnis;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected internal void OnPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
        }
    
        private string _Ergebnis;
        public string Ergebnis
        {
            get { return _Ergebnis; }
            set
            {
                if (_Ergebnis == value) return;
                _Ergebnis = value;
                _Model.Ergebnis = value;
                OnPropertyChanged("Ergebnis");
            }
        }
    
        private ICommand zahlcommand;
        public ICommand ZahlCommand
        {
            get 
            {
                if (zahlcommand == null)
                {
                    zahlcommand = new CommandBase((param) => this.doStuff());
                }
                return zahlcommand;
            }
        }
    
        private void doStuff()
        {
            Ergebnis  = "1";          
        }   
    }

    XAML:

    <Grid>
        <TextBox x:Name="Textbox" HorizontalAlignment="Left" Height="23" Margin="188,34,0,0" TextWrapping="Wrap" Text="{Binding Ergebnis}" VerticalAlignment="Top" Width="120"/>
        <Button HorizontalAlignment="Left" Command="{Binding ZahlCommand}" Margin="215,185,0,0"  VerticalAlignment="Top" Width="75">1</Button>
    </Grid>

    • Als Antwort markiert Flier94 Montag, 15. Juli 2013 14:25
    Montag, 15. Juli 2013 14:15
  • Hallo Thomas. 

    Danke! Es hat funktioniert! Ich hatte noch einen Fehler im Code gehabt!

    Gruß Flier


    • Bearbeitet Flier94 Montag, 15. Juli 2013 14:36 Fehler
    Montag, 15. Juli 2013 14:24
  • Eine Frage habe ich jedoch noch.

    Kann ich irgendwie den Content des Buttons mitgeben? Ich kann dann nämlich wenn ich Button 1 Drücke automatisch ein 1 hinzufügen lassen. Danke nochmals

    Flier

    Montag, 15. Juli 2013 14:38
  • Hallo Flier,

    das machst du am Einfachsten indem du den Content des Buttons an das Ergebnis bindest: 

    <Button HorizontalAlignment="Left" Command="{Binding ZahlCommand}" Margin="215,185,0,0"  VerticalAlignment="Top" Width="75" Content="{Binding Ergebnis}" />
    

    Dann am besten aus dem Ergebnis ein int machen:

    private int _Ergebnis;
    public int Ergebnis
    {
        get { return _Ergebnis; }
        set
        {
            if (_Ergebnis == value) return;
            _Ergebnis = value;
            _Model.Ergebnis = value;
            OnPropertyChanged("Ergebnis");
        }
    }

    auch in der Model.cs:

    public int Ergebnis { get; set; }       

    und dann die doStuff-Methode anpassen:

    private void doStuff()
    {
        Ergebnis++;       
    }   

    Montag, 15. Juli 2013 14:52
  • Ok. Danke!!!

    Gruß Flier

    Montag, 15. Juli 2013 14:59
  • Hi Thomas.

    Ich habe mir das Programm noch einmal angeschaut. Ich wollte nicht den Namen des Buttons ändern, sondern den Namen des Buttons an das Ergebnis dran hängen.

    private void doStuff()
    {
        Ergebnis+=ContentButton;     
    }  

    Wie mache ich das? Danke für die Hilfe!

    Gruß Flier

    Dienstag, 16. Juli 2013 07:38