Verfasst von: bletra | 12. Mai 2011

WPF: Von Spaghetticode zu MVVM – Teil 7 von 9

In dieser Artikelserie möchte ich eine einfache Applikation, in eine testbare Applikation nach dem MVVM-Pattern umwandeln:

  1. Beispielapplikation mit Spaghetticode
  2. Refactoring 1: Model
  3. MVC, MVP, Presentation Model
  4. MVVM
  5. ICommand
  6. Binding
  7. Refactoring 2: ViewModel
  8. Refactoring 3: View
  9. Zusammenfassung

ViewModel

Im letzten Artikel haben Sie bereits ein sehr einfaches ViewModel kennen gelernt. Welche Zustände und Befehle benötigt die Feed-Applikation?

  • Befehle:
    • AddFeed (enabled, falls im Adressfeld etwas eingegeben wurde)
    • Save (immer möglich)
  • Zustände/Properties:
    • Eine sortierte Liste der Titel der Feeds
    • Text im Adressfeld
    • Zustand des Cursors (hierfür führen wir eine weitere Eigenschaft ein: protected IsBusy)
    • Message, hier hinterlegen wir Fehler- und Statusmeldungen.

Das ViewModel kennt die View nicht, aber das Model. Dieses gestalten wir austauschbar über ein Interface – wie in Teil 3 beim MVP-Pattern dargestellt. Damit ergibt sich folgender Code:

public class FeedsViewModel : BaseViewModel
{
    private ICommand _addCmd;
    private ICommand _saveCmd;
    private Model.IFeedProvider _model;
    private string _msg;
    private string _address;
    private bool _isBusy = false;

    public FeedsViewModel()
        : this(new Model.FeedModel())
    {

    }

    public FeedsViewModel(Model.IFeedProvider model)
    {
        _model = model;
        _msg = "";
        _address = "";
        _addCmd = new DelegateCommand((param) => AddFeed(), (param) => _address.Length > 0);
        _saveCmd = new DelegateCommand((param) => Save());
    }

    public string Address
    {
        get { return _address; }
        set
        {
            _address = value;
            NotifyPropertyChanged("Address");
        }
    }

    public ICommand AddCmd
    {
        get { return _addCmd; }
    }

    public ICommand SaveCmd
    {
        get { return _saveCmd; }
    }

    public string Msg
    {
        get { return _msg; }
        protected set
        {
            _msg = value;
            NotifyPropertyChanged("Msg");
        }
    }

    public Cursor Cursor
    {
        get
        {
            if (_isBusy)
            {
                return Cursors.Wait;
            }
            return Cursors.Arrow;
        }
    }

public List Feeds
    {
        get
        {
            return _model.Feeds.Keys.OrderBy(k=>k).ToList();
        }
    }
    protected bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            _isBusy = value;
            NotifyPropertyChanged("IsBusy");
            NotifyPropertyChanged("Cursor");
        }
    }
    private void AddFeed()
    {
        IsBusy = true;
        Msg = ""; //do not use private member to raise events for the view
        try
        {
            _model.AddFeed(_address);
            Address = "";
            NotifyPropertyChanged("Feeds");
        }
        catch (Exception ex)
        {
            Msg = ex.Message;
        }
        IsBusy = false;
    }
    private void Save()
    {
        try
        {
            _model.SaveFeeds();
            Msg = "Saved feeds successfully.";
        }
        catch (Exception ex)
        {

            Msg = "Error: " + ex.Message;
        }
    }
}

Mit diesem ViewModel können wir die ursprüngliche Funktionalität (etwas robuster) in den XAML-Code der View einbauen. Dies tun wir im nächsten Artikel.

Advertisements

Responses

  1. […] Refactoring 2: ViewModel […]

  2. […] Refactoring 2: ViewModel […]

  3. […] ViewModel, WPF, XAML « WPF: Von Spaghetticode zu MVVM – Teil 5 von 9 WPF: Von Spaghetticode zu MVVM – Teil 7 von 9 […]

  4. […] in C# / VisualStudio | Schlagwörter: Binding, Command, MVVM, View « WPF: Von Spaghetticode zu MVVM – Teil 7 von 9 WPF: Von Spaghetticode zu MVVM – Teil 9 von 9 […]

  5. […] Refactoring 2: ViewModel […]

  6. […] Refactoring 2: ViewModel […]

  7. […] Refactoring 2: ViewModel […]


Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

Kategorien

%d Bloggern gefällt das: