WPF: PropertyChangedCallback nur einmal ausgelöst
Ich habe ein user control, das macht eine DependencyProperty genannt VisibileItems
Jedes mal, wenn die Eigenschaft aktualisiert wird, muss ich zum auslösen eines anderen Ereignisses.
Um das zu erreichen, habe ich ein FrameworkPropertyMetadata mit PropertyChangedCallback Veranstaltung.
Für einige Grund, dieses event wird nur einmal aufgerufen, und nicht Auslöser der nächsten Zeit VisibleItems geändert wird.
XAML:
<cc:MyFilterList VisibleItems="{Binding CurrentTables}" />
CurrentTables ist eine DependencyProperty auf MyViewModel. CurrentTables wird oft geändert. Ich kann binden ein weiteres WPF-Steuerelement zu CurrentTables, und ich sehe die änderungen in der Benutzeroberfläche.
Hier ist die Art, wie ich WLAN VisibleItems mit PropertyChangedCallback
public static readonly DependencyProperty VisibleItemsProperty =
DependencyProperty.Register(
"VisibleItems",
typeof(IList),
typeof(MyFilterList),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(VisiblePropertyChanged))
);
public IList VisibleItems {
get { return (IList)GetValue(VisibleItemsProperty); }
set { SetValue(VisibleItemsProperty, value); }
}
durch treten in VisiblePropertyChanged, ich kann sehen, dass es wird ausgelöst, das erste mal CurrentTables festgelegt wird. nicht aber die folgenden Male.
UPDATE
wie einige von Euch bezweifelt, dass die Art und Weise CurrentTables geändert wird, ist es wieder zugewiesen komplett auf ändern:
OnDBChange()...
CurrentTables = new List<string>(MainDatabaseDataAdapter.GetTables(this.SelectedServer, this.SelectedDatabase));
diese Zeile aufgerufen wird, wird bei jeder änderung, aber meine VisiblePropertyChanged-handler aufgerufen wird, wird nur die erste Zeit.
UPDATE
wenn ich diesen VisibleItems direkt, der handler wird aufgerufen, jedes mal!
TestFilterList.VisibleItems = new List<string>( Enumerable.Range(1, DateTime.Now.Second).ToList().Select(s => s.ToString()).ToList() );
So, wie es aussieht, das problem ergibt sich aus der DependencyProperty (VisibleItems) und ein anderes anschauen DependencyProperty (CurrentTables). Irgendwie ist die Bindung funktioniert auf den ersten Eigenschaft zu ändern, aber nicht auf die nachfolgenden?
Versuch untersuchen dieses Problem mit snoop wie einige von Euch vorgeschlagen.
- Sind Sie sicher, dass die Bindung erhalten bleibt? Ich würde Snoop, um zu überprüfen, dass die Bindung der Aktualisierung der VisibleItems Eigenschaft richtig.
- Sie impliziert, aber nicht explizit: "sind Sie sicher, dass
VisibleItems
tatsächlich änderungen auf einen anderen Wert, ohne die Eigenschaft geändert callback aufgerufen wird? - Rick, ja ich bin sicher, ich kann Schritt für Schritt durch und sehen, dass es aufgerufen wird, und jetzt habe ich eine "neue Liste" bei jedem Anruf, um sicher zu sein es ist nicht die gleiche Instanz. aber auch wenn man sich den code können Sie sehen, dass es wird die Liste aus der Datenbank zu jeder Zeit.
- Das beweist, dass CurrentTables verändert sich nicht beweisen, dass VisibleItems verändert. Ihre Bindung gebrochen oder so etwas. Ich vermute, dass VisibleItems ist eigentlich nicht ändern, das ist, warum ich empfehle, mit Snoop zu stellen Sie sicher, dass die Bindung funktioniert.
- kramer, Recht auf. ich habe einen anderen test und es tatsächlich scheint, dass das problem irgendwo zwischen VisibleItems und CurrentTables... müssen tun einige Untersuchung, um zu sehen, warum Sie funktionieren auf Anhieb, aber nicht die anschließende..
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie auf der Einstellung eines 'lokalen' Wert (d.h. die Zuweisung direkt auf eine dependency property-setter) zu einer Abhängigkeitseigenschaft, der hat auch ein
OneWay
binden? Wenn ja, Einstellung der lokale Wert wird, entfernen Sie die Bindung, wie erwähnt, auf der die MSDN-Abhängigkeitseigenschaft überblick:Die Abhängigkeitseigenschaft Mechanismus nicht viel anderes es tun kann, wenn es wird gebeten, zu speichern einem lokalen Wert einer Abhängigkeitseigenschaft. Es kann nicht senden der Wert durch die Bindung, da die Bindung 'Punkte' der falsche Weg. Nach dem festlegen an den lokalen Wert, es ist nicht mehr mit den Werten, die es bekam, die aus der Bindung. Da ist es nicht mit den Werten, die aus der Bindung nicht mehr, es entfernt die Bindung.
Sobald die Bindung Weg ist, die
PropertyChangedCallback
wird nicht mehr aufgerufen, wenn die source-Eigenschaft für die Bindung Ihren Wert ändert. Dies kann, warum der Rückruf nicht aufgerufen.Wenn Sie die Bindung zu
TwoWay
, die Bindungs-system hat irgendwo zu speichern, die 'lokalen' Wert, den Sie festgelegt haben: in der Bindung der source-Eigenschaft. In diesem Fall gibt es keine Notwendigkeit zu beseitigen, die die Bindung als dependency property-Mechanismus können Sie den Wert speichern in der source-Eigenschaft.Diese situation führt nicht zu einem stack-überlauf, da passiert Folgendes:
PropertyChanged
,PropertyChanged
Ereignis, prüft neue Wert der Eigenschaft source ist, findet, dass es nicht geändert hat und nichts weiter.Der entscheidende Punkt hier ist, dass, wenn Sie Feuer ein
PropertyChanged
Ereignis für eine Eigenschaft , deren Wert sich nicht geändert hat, jedePropertyChangedCallback
s an die Abhängigkeit von Eigenschaften gebunden ist, um Ihr Eigentum nicht aufgerufen werden.Einfachheit halber habe ich ignoriert
IValueConverter
s in den oben genannten. Wenn Sie haben einen Konverter, stellen Sie sicher, dass es korrekt konvertieren von Werten in beide Richtungen. Ich habe auch angenommen, dass die Eigenschaft am anderen Ende ist ein view-Modell-Eigenschaft auf ein Objekt der UmsetzungINotifyPropertyChanged
. Es hätte eine weitere Abhängigkeitseigenschaft an der Quelle Ende der Bindung. Die Abhängigkeitseigenschaft Mechanismus Griff, der auch.Wie es geschieht, WPF (und Silverlight) enthalten keine Erfassung der stack überläuft. Wenn Sie in einem
PropertyChangedCallback
setzen Sie den Wert der Abhängigkeitseigenschaft zu unterschiedlich sein, um den neuen Wert (z.B. durch das Inkrementieren einer integer-valued property oder anfügen eine Zeichenfolge an einen string-Wert-Eigenschaft), erhalten Sie einen stack-überlauf.Ich habe das gleiche Problem in meinem code und Lukas richtig ist. Ich rief SetValue durch mystake innerhalb der PropertyChangedCallback verursacht eine potenzielle Endlosschleife. WPF dies verhindern, deaktivieren schweigend den Rückruf !!
meine WPF-UserControl ist
mein C# - Eigenschaft Hinweis:
meine WPF-Eigenschaft
Die Sie möglicherweise ein Problem, bei dem der Inhalt der Sammlung wird sich verändern, aber nicht die tatsächliche Instanz. in diesem Fall werden Sie wollen, um die Verwendung einer ObservableCollection und tun Sie etwas wie dieses:
Wenn Sie nur ein Exemplar einer
MyFilterList
- und set -VisibleItems
über code wie diesen:Werden Sie wahrscheinlich sehen die PropertyChangedCallback passieren jeden mal. Bedeutung, ist das problem mit der Bindung, nicht der Rückruf. Stellen Sie sicher, dass Sie nicht bindend Fehler, du bist Anhebung
PropertyChanged
, und du bist nicht das brechen der Bindung (z.B. durch das setzenVisibleItems
im code)