2009-03-05 9 views
1

Ich bin in einer Situation, in der ich von einer externen Quelle informiert werde, dass eine bestimmte Entität außerhalb meines aktuellen Datenkontexts geändert wurde. Ich bin in der Lage, die Entität und Anrufauffrischung wie folgt zu findenDataContext Aktualisieren und PropertyChanging & PropertyChanged Ereignisse

MyDataContext.Refresh (RefreshMode.OverwriteCurrentValues, myEntity);

und die Eigenschaften, die für die Entität geändert wurden, werden korrekt aktualisiert. Keines der INotifyPropertyChanging INotifyPropertyChanged scheint jedoch bei der Aktualisierung ausgelöst zu werden, sodass meine Benutzeroberfläche falsche Informationen anzeigt.

Ich bin mir bewusst, dass Refresh() fehlschlägt, die richtigen Eigenschaft Getter und Setter auf der Entität zu verwenden, um die Änderungsbenachrichtigungsereignisse auszulösen, aber vielleicht gibt es eine andere Möglichkeit, dasselbe zu erreichen?

Mache ich etwas falsch? Gibt es eine bessere Methode als Refresh? Wenn Refresh die einzige Option ist, hat jemand eine Arbeit?

Antwort

2

Ich hatte ein ähnliches Problem. Ich war an eine TreeView gebunden und musste Refresh aufrufen, wenn der Benutzer einen Bearbeitungsvorgang abbrach. Die Refresh() Methode gibt alle ursprünglichen Werte zurück, aber dies wurde nicht in meiner TreeView-Benutzeroberfläche widergespiegelt. Nach Rücksprache mit dem allmächtigen Google, stieß ich auf diese Lösung:

CollectionViewSource.GetDefaultView(treeViewClusters.ItemsSource).Refresh(); 

Das ist mein TreeView zu zwingen, scheint alles zu aktualisieren. Der einzige Nachteil (und es ist ein ziemlich großer) ist, dass es scheint, alle Baumknoten zusammenzufallen, was dazu führt, dass der Benutzer seinen Platz verliert. Ich könnte genauso gut meine ItemsSource auf null und wieder zurück setzen ... den gleichen Effekt, obwohl diese Methode einfacher wäre, wenn Sie einen Haufen gebundene Textfelder oder etwas hätten, da Sie nicht jedes einzelne neu binden müssten.

Gibt es eine bessere Lösung als diese?

EDITED: Ja, es gibt ...

Ein smarter-als-me Mitarbeiter von mir mit dieser Lösung kam, die den Trick zu tun scheint. In Ihrem Teilklasse für das Linq2Sql Objekt, fügen Sie den folgenden Code ein:

public void SendPropertiesChanged() 
{ 
    foreach (System.Reflection.PropertyInfo prop in this.GetType().GetProperties()) 
    SendPropertyChanged(prop.Name); 
} 

Das können Sie dies einfach anrufen im Anwendungscode:

context.Refresh(RefreshMode.OverwriteCurrentValues, employee); 
employee.SendPropertiesChanged(); 

Alle Elemente der Benutzeroberfläche die Nachricht erhalten, und aktualisieren sich angemessen . Dies funktioniert sogar für TreeView-Steuerelemente und solche Dinge, bei denen die Benutzeroberfläche beim Aktualisieren der Bindungen nicht zurückgesetzt zu werden scheint.

0

Wenn Sie wissen, Refresh() aufzurufen, warum nicht einfach weitermachen und die Benutzeroberfläche an diesem Punkt sowieso aktualisieren?

PropertyChanging und PropertyChanged werden aufgerufen, indem der Setter für eine von LINQtoSQL DBML generierte Entitätsklasse aufgerufen wird. Aufruf Refresh() tut das nicht:

[Column(Storage="_DisplayName", DbType="VarChar(50) NOT NULL", CanBeNull=false)] 
public string DisplayName 
{ 
    get 
    { 
     return this._DisplayName; 
    } 
    set 
    { 
     if ((this._DisplayName != value)) 
     { 
      this.OnDisplayNameChanging(value); 
      this.SendPropertyChanging(); 
      this._DisplayName = value; 
      this.SendPropertyChanged("DisplayName"); 
      this.OnDisplayNameChanged(); 
     } 
    } 
} 
+0

Rex, Das Refresh() ist auf einem Controller/"Fast Business Layer" -Ebene erfolgt, es ist nicht in der Nähe der Benutzeroberfläche so eine manuelle Aktualisierung ist nicht in Frage. Wenn Refresh() die Enitity-Daten ändert, sollte es veränderte Ereignisse auslösen - die Tatsache, dass es nicht funktioniert, scheint mir eine grobe Aufsicht zu sein. – Scott

+0

@Scott vielleicht ist es ein Versehen, aber das ist Code, den wir nicht ändern können, während deiner ist. Warum fügen Sie Ihrer DataContext-Klasse kein Ereignis hinzu, das Sie beim Aufruf von Refresh() aufrufen und an das von der Benutzeroberfläche anfügen? Das liegt nahe am SoC, den Sie von einem Ereignis in der Entität erhalten. –