INotifyPropertyChanged

Act 1 Scene 2 – Naming Conventions

Thinking a lot about INotifyPropertyChanged I visited Dan Wahlin’s and John Papa’s talks on the DevConnections in Karlsruhe/Germany. They also “discussed” about the Naming convention 😉

I, for my opinion, see the following naming as the best:

  class MyViewModelBase : INotifyPropertyChanged

  {

    public event PropertyChangedEventHandler PropertyChanged;

 

    public void NotifyPropertyChanged(string name)

    {

      var handeler = PropertyChanged;

      if(handeler != null)

        handeler(this, new PropertyChangedEventArgs(name));

    }

  }


The consumer of the event uses OnPropertyChanged as of a button click, the handler would be OnClick.

  class MyViewModel : MyViewModelBase

  {

    public MyViewModel()

    {

      PropertyChanged += OnPropertyChanged;

    }

    void OnPropertyChanged(object sender, PropertyChangedEventArgs e)

    {

      throw new NotImplementedException();

    }

  }

So why I think it should be this way? Think about an interface ISayHello.

  interface ISayHello

  {

    event Action Hello;

  }

The method to fire the event should be SayHello. Nobody would say FireSayHello, RaiseSayHello or anything in the real world. What else useful than raise/fire could be done with an event? So those words are redundant.

  class HelloSayer : ISayHello

  {

    public event Action Hello;

    public void SayHello()

    {

      var handler = Hello;

      if(handler != null)

        handler();

    }

  }
The listener of again uses OnHello to handle its listening.
  class Listener

  {

    private readonly HelloSayer friend;

    public Listener()

    {

      friend = new HelloSayer();

      friend.Hello += OnHello;

    }

    private static void OnHello()

    {

      Debug.Print("Goodby");

    }

  }

Conclusion

Every time an interface is like “INotifyPropertyChanged” => “I notify (you for every) property changed” the rising method should be the name without the interface-I and the event itself should be named like the fact the event informs about.

To be discussed (#nossued)

Advertisements
Veröffentlicht unter DotNetGerman Bloggers, Softwareentwicklung | Verschlagwortet mit , | 2 Kommentare

Reactive Extensions können gesprächig sein

Ok, manchmal sind die Reactive Extensions sehr gesprächig im vergleich zur “klassischen” Programmierung.

Die Aufgabe: Auf das Event NotifyPropertyChanged mit dem PropertyNamen “PicturePath” hören und eine Liste neu füllen.

Klassisch

Handler einhängen

PropertyChanged += HandlePicturePathChanged;

Prüfung in der Methode.

void HandlePicturePathChanged(object sender, PropertyChangedEventArgs e)
{
  if (e.PropertyName != „PicturePath“)
    return;

Reactive

Subscription auf Event-Handler

Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(h => PropertyChanged += h, h => PropertyChanged -= h).
Where(e => e.EventArgs.PropertyName ==
„PicturePath“).Subscribe(_ => HandlePicturePathChanged());

Die Methode kümmert sich nur um “ihre Dinge”.

void HandlePicturePathChanged()
{

Meinung (gefühlt)

Der reaktive Ansatz ist besser im Sinne von “Seperation of Concerns”, dafür aber sehr gesprächig. Da ich ungerne viel tippe bin ich in diesem Fall nicht überzeugt.

Schöner wird es, wenn man auf mehrere Teilmengen des Eventstroms wartet.

var propChanged =

Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(h => PropertyChanged += h, h => PropertyChanged -= h);

propChanged.Where(e => e.EventArgs.PropertyName == „PicturePath“).Subscribe(_ => HandlePicturePathChanged());

propChanged.Where(e => e.EventArgs.PropertyName == „ActiveProject“).Subscribe(_ => HandleActiveProjectChanged());

(Ich mag Rx) 

Veröffentlicht unter DotNetGerman Bloggers, Softwareentwicklung | Verschlagwortet mit , | Kommentar hinterlassen

MVVM DynamicViewModel

Ok, was will man denn eigentlich?
Man hat schon die Daten in einem Model wie z.B.

class Customer
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

und benötigt dazu ein ViewModel.
Microsoft sieht das so: Handarbeit!

class MsViewModel : INotifyPropertyChanged
{
  private readonly Customer _customer;
  public MsViewModel(Customer customer)
  {
    _customer = customer;
  }

  public string FirstName
  {
    get { return _customer.FirstName; }
    set
    {
      if (value == _customer.FirstName)
        return;
      _customer.FirstName = value;
      NotifyPropertyChanged(„FirstName“);
    }
  }

  public string LastName
    . . .

  #region INotifyPropertyChanged Members
  public event PropertyChangedEventHandler PropertyChanged;
  protected void NotifyPropertyChanged(string name)
  {
    var handler = PropertyChanged;
    if (handler == null)
      return;
    handler(this, new PropertyChangedEventArgs(name));
  }
  #endregion
}

Das ist Fleißarbeit, Fehleranfällig, nicht refakturierbar, ätzend, usw..

Alternativ könnte ein Codegenerator geschrieben werden – mir persönlich nicht ausreichend. Ich würde das gerne so sehen:

class MyViewModel : DynamicViewModel<Customer>
{
}

Weitere Ziele der Entwicklung:

  • Blendability (Bindungen werden in Expression Blend angezeigt)
  • Automatisches INotifyPropertyChanged
  • Mehrere Modelle können in einem ViewModel zusammengefasst werden
  • Zusätzliche Properties als Ergänzung zu denen des/der Models
  • Aktualisierung voneinander abhängiger Properties
  • Filterung der Properties (nicht alle werden dem View bereitgestellt

Los gehts. Erst mal die Grundfunktion, also die Properties des Models im View bereitstellen.

Der erste Ansatz ist ExpandoObject – geht aber nicht weil sealed, eine Schutzbehauptung im Sinne von: Oh, das ist schon gut, aber ob es so bleiben kann weiß ich noch nicht Zwinkerndes Smiley

Also direkt von DynamicObject ableiten. Mehr Arbeit aber geht – fast. Der Designer kann jetzt die Bindungen nicht mehr Anzeigen.

Blendability

Eine Hauptforderung ist, dass das Ergebnis mit Expression Blend bearbeitet werden kann. Ohne dies ist die Zusammenarbeit mit einem Designstudio nicht möglich. Leider ergab diese Forderung die ersten Probleme.

Die Lösung ist die zusätzliche Implementierung von ICustomTypeDescriptor.

Automatisches INotifyPropertyChanged

Ergibt sich ganz einfach in der Implementierung von TrySetMember aus DynamicObject.

Mehrere Modelle

Im einfachsten Fall basiert ein ViewModel nur auf einem Model. Aber schon eine einfache Beziehung erfordert die Bindung an mehrere Modelle (z.B. Person und Firma).

Die Implementierung als Generic ist für diesen Fall nicht flexibel genug.

DynamicViewModel<Customer>

Ich habe mich deshalb entschieden eine Methode AddModel einzuführen. Daraus ergibt sich außerdem der Vorteil, dass bereits vorhandenen Instanzen des Models im ViewModel verwendet werden können.

Zusätzliche Properties

Als Ergänzung zu den Properties des Models können im angeleiteten ViewModel neue Properties eingeführt werden. Ich habe hierbei zwei Varianten implementiert.

class MyViewModel : DynamicViewModel
{
  public string MyProp { get; set; }

Die public Properties der Ableitung stehen ganz normal zur Verfügung. Mit automatischer Unterstützung von INotifyPropertyChanged!!!

Außerdem können “noch dynamischer” über einen Indexer zur Laufzeit hinzugefügt werden.

public object this[string name]

this[„Test“] = „kuckuck“;

Werden diese im Konstruktor hinzugefügt stehen sie auch im Designer zur Verfügung!!!

Binding

Aktualisierung voneinander abhängiger Properties

Im speziellen ViewModel will man gewöhnlich weitere, aus den Daten des zugrunde liegenden Models berechnete Properties bereit stellen. Hierbei gibt es folgende Probleme. Erstens ist zur Kompilierzeit der Typ der/des Models nicht bekannt. Der Zugriff muss also über den Indexer erfolgen (nicht schön, ich bin noch am Grübeln). Außerdem muss zur korrekten Weiterleitung von  INotifyPropertyChanged bekannt sein, auf welchen Properties das neue basiert. Hierzu wird das Attribut DependsOn verwendet. Gibt es schon im Framework, muss aber hier für die eigenen Zwecke auch selbst implementiert werden.

[DependsOn(„FirstName“)]
public int LenOfFirstName { get { return this[„FirstName“].ToString().Length; } }

Filterung der Properties

Um nicht alle Properties des Models im Designer sichtbar zu machen können die zu versteckenden mit dem Browsable(false) Attribut gekennzeichnet werden.

[Browsable(false)]

Gibt es auch schon im Framework, muss aber auch hier für die eigenen Zwecke auch selbst implementiert werden.

Fazit

Für den ersten Moment bin ich mit der Funktionalität sehr zufrieden.

Auf dem OpenSpace im Juli in Karlsruhe werde ich auf jeden Fall eine Runde darüber diskutieren…

 


 

Veröffentlicht unter DotNetGerman Bloggers, Softwareentwicklung | Verschlagwortet mit , | 1 Kommentar

Völlig losgelöst!–der Office-Hub

Über die einzige Möglichkeit, ein Office Dokument zu synchronisieren (per E-Mail) hab ich mich schon generft.

Heute mehr über die völlige Konzeptfreiheit der Bedienung.

Viele Jahre hat Microsoft daran gearbeitet es den Anwendern einfacher zu machen. Das geht soweit, dass man das Speichern seiner Dokumente nicht mehr vergessen kann.

Office am PC speichert immer mal wieder zwischen,

imageOffice Web App hat gar keine Funktion zum speichern mehr!

 

 

 

Jetzt kommt Windows Phone ins Spiel

In keiner Standardanwendung muss man Speichern, in den Einstellungen gibt es einen Button Ok und Abbrechen (ich kann hier keinen Screenshot einfügen weil das nicht mehr unterstützt wird – ein sehr gute Idee um Dokumentationen einfacher zu gestalten – ohne all diese bunten Bilder).

Microsoft Excel Mobile, wie es hier heißt oder Excel Mobile 2010 wie es in den ersten Schritten genannt wird schafft es!

Excel öffnen, einen Wert in eine Zelle eintragen, Home – Taste drücken und gut.

Zurück, nächsten Wert eintragen, auch gut.

Aber HALT! – Zwischendurch war Excel nur “schlafengelegt”.

Wird Excel beendet, so werden auch die Daten kommentarlos verworfen.

Also auf die suche gehen…

So geht das ganz (und gar nicht) einfach:

Excel öffnen, einen Wert in eine Zelle eintragen, Zurück – Taste drücken um die Tastatur loszuwerden und das Menü wieder zu sehen. „Mit “…” weitere Menübefehle aufrufen, runter scrollen, weiter runter, und siehe da, hier ist eine Speicherfunktion!

So einfach ist doch das speichern von Daten, wenn es ein durchgängiges Konzept gibt!

Hinweis: Die Office-Truppe hatte noch nie so richtig was mit Microsoft zu tun.

Veröffentlicht unter Windows Phone 7 | Verschlagwortet mit , , | Kommentar hinterlassen

Windows Phone 7 – Zusammenfassung 2010

Das Christkind war so nett und hat mir ein Samsung Omnia 7 gebracht Zwinkerndes Smiley

Die Woche “zwischen den Jahren” habe ich jetzt damit zugebracht alles entsprechend einzurichten.

Hier die Liste der Möglichkeiten und Unmöglichkeiten:

Es geht, wenn man sich zwischen Beelzebub (Hotmail) und Teufel (Google-Mail) unterscheidet seine Kontakte, E-Mails und den Kalender zu synchronisieren. Es muss eben alles in der Cloud sein!

Hotmail kann keine Kontaktfotos

Die Foren sind voll von unsinnigen Hinweisen ob, wie und überhaut wie man das löst.
Die Antwort: Es kann nicht gehen, da Hotmail überhaupt keine Kontaktfotos unterstützt (DB-Feld nicht vorhanden). Die dort sichtbaren Fotos stammen aus Messenger oder Facebook. Also nicht jammern, warten auf einen Hotmail Update.

P.S. Google-Mail kann das.

Firmennamen maximal 40 Zeichen

Wir schreiben das Jahr 2010 und es gibt immer noch Software (Hotmail) das Felder auf 40 Zeichen begrenzt. Je nachdem mit welchem Outlook und Connector man die Synchronisierung vornimmt kommt eine Meldung, dass man die Bezeichnungen kürzen kann oder die betreffenden Kontakte werden schlicht nicht importiert (Kommentarlos).

Office Dokumente Synchronisieren

Ich konnte lange die notwendigen Einstellungen nicht finden…
Dann habe ich die entsprechende Seite in der Hilfe gefunden: Synchronisieren Sie Ihre Office Dokumente einfach per E-Mail…
Kein weiterer Kommentar.

OneNote Synchronisieren

Immerhin kann man ein Notizbuch automatisch synchronisieren, es muss aber “Persönlich (Web)” benannt sein.
Ja geht es denn noch?

Copy & Paste

Eigentlich wollte ich dazu nichts sagen. Mit dem ersten Update im Februar soll das gegessen sein.
Ich hab es trotzdem schon mehrmals vermisst…

Consumer vs. Business

Microsoft sagt das sei in der momentanen Version ausschließlich ein Consumer-Gerät.

Wie in aller Welt kommt man dann auf die Idee, dass eine sinnvolle Synchronisierung nur mit Exchange und SharePoint funktioniert???

Die eigene Anwendung

Mein gerät ist bereits im AppHub registriert und ich hab einen ersten Test gemacht.

Jetzt fehlt mir eine Idee was man denn so als Übungsaufgabe programmieren könnte – Vorschläge willkommen.
Meinen KVV-Abfahrtsmonitor kann ich ja leider nicht realisieren da sich die KVV weigert eine entsprechende Schnittstelle anzubieten.

Ausblick

Ich freue mich schon auf ein Ereignisreiches 2011 und lebe bis dahin mit den Workarounds…

Euch allen ein gutes neues Jahr!

Veröffentlicht unter Windows Phone 7 | Verschlagwortet mit | Kommentar hinterlassen

So jetzt bin ich also auc bei WordPress gelandet

MS kriegt sowas also nicht hin 😉
(ist eben ohne BussinessImpact)

Veröffentlicht unter Uncategorized | Kommentar hinterlassen

Auf der Suche nach einem neuen Hoster…

Ich war jetzt ein ganzes Jahr sehr zufrieden mit HostEurope.

Nach der Umstellung auf ein größeres Paket – nur noch Probleme.

Die suche nach einem neuen Hoster gestaltet sich nicht so einfach wie man denkt.
Ich wollte doch besser werden mit der zugesicherten Verfügbarkeit.

Hier die Klauseln in den AGBs.

QualityHosting AG

QualityHosting wird die vom Kunden bestellten Dienste in Übereinstimmung mit der
jeweils anwendbaren Leistungsbeschreibung und etwaigen Service Level Agreements
erbringen. Aufgrund der Art der Dienste stellen die Leistungsbeschreibungen und Service
Level Agreements weder das Versprechen eines konkreten Erfolgs noch eine Garantie
dar.
(und bei der Anfrage sowas von unfreundlich am Telefon)

Host Europe GmbH

QualityHosting wird die vom Kunden bestellten Dienste in Übereinstimmung mit der

Sollte das Service Level von 99,9% unterschritten werden, gewährt der Provider eine Gutschrift in
Höhe einer Tagesmiete (1/30-Monatsmiete) je angefangene 30 Minuten Unterschreitung des Service
Levels, jedoch maximal 50% der Monatsmiete der betroffenen Dienstleistung.

…ich will doch einfach nur dass es geht!

Veröffentlicht unter Uncategorized | Kommentar hinterlassen