Hier ist eine kleine statische Klasse von Erweiterungsmethoden, die ich für WPF geschrieben habe - es ermöglicht Ihnen, einen EventHandler oder einen Aktionsrückruf für das Ändern von DependencyProperty auf jedem DependencyObject zu registrieren. Änderungen am Abhängigkeitsobjekt sind nicht notwendig.
Es verhindert auch Rekursion (das heißt, wenn Sie die gleiche Eigenschaft während des Rückrufs ändern, etc ..)
Es nutzt die DependencyPropertyDescriptor dass @ScottBilas verknüpft.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
namespace BrainSlugs83.Writes.Too.Much.Code
{
public static class WpfExtensions
{
public static void OnPropertyChanged<T>(this T obj, DependencyProperty prop, Action<T> callback) where T : DependencyObject
{
if (callback != null)
{
obj.OnPropertyChanged(prop, new EventHandler((o, e) =>
{
callback((T)o);
}));
}
}
public static void OnPropertyChanged<T>(this T obj, DependencyProperty prop, EventHandler handler) where T : DependencyObject
{
var descriptor = DependencyPropertyDescriptor.FromProperty(prop, typeof(T));
descriptor.AddValueChanged(obj, new EventHandler((o, e) =>
{
if (handler != null)
{
if (o == null) { handler(o, e); }
else
{
lock (PreventRecursions)
{
if (IsRecursing(obj, prop)) { return; }
SetIsRecursing(obj, prop, true);
}
try
{
handler(o, e);
}
finally
{
SetIsRecursing(obj, prop, false);
}
}
}
}));
}
#region OnPropertyChanged Recursion Prevention
private static readonly Dictionary<object, List<DependencyProperty>> PreventRecursions = new Dictionary<object, List<DependencyProperty>>();
private static bool IsRecursing(object obj, DependencyProperty prop)
{
lock (PreventRecursions)
{
List<DependencyProperty> propList = null;
if (PreventRecursions.ContainsKey(obj))
{
propList = PreventRecursions[obj];
}
return propList == null ? false : propList.Contains(prop);
}
}
private static void SetIsRecursing(object obj, DependencyProperty prop, bool value)
{
lock (PreventRecursions)
{
List<DependencyProperty> propList = null;
if (PreventRecursions.ContainsKey(obj))
{
propList = PreventRecursions[obj];
}
if (propList == null)
{
if (!value) { return; }
propList = PreventRecursions[obj] = new List<DependencyProperty>();
}
if (value)
{
if (!propList.Contains(prop))
{
propList.Add(prop);
}
}
else
{
while (propList.Contains(prop))
{
propList.Remove(prop);
}
if (!propList.Any())
{
propList = PreventRecursions[obj] = null;
}
}
}
}
#endregion
public static bool IsInDesignMode(this DependencyObject obj)
{
try
{
return DesignerProperties.GetIsInDesignMode(obj);
}
catch { /* do nothing */ }
return false;
}
}
}
Ich bin irgendwie verwirrt, warum brauchen Sie das. Normalerweise ist es umgekehrt, wenn DP für Bindungen verwendet werden und wenn diese sich ändern, möchten Sie die DP informieren. Warum würdest du es anders herum brauchen? –
Was meinst du damit rückwärts @Omribitan? Dies ist Standard-WPF. Wenn ich den Wert einer Abhängigkeitseigenschaft ändere, wissen alle an diese Eigenschaft gebundenen Dinge sofort darüber. Dies ist eine Art von Abhängigkeitseigenschaften - und die Datenbindung von WPF basiert auf diesem Konzept. – BrainSlugs83
@ BrainSlugs83 Denken Sie an die Sichtbarkeit eines Steuerelements, das an eine Eigenschaft der ViewModel-Klasse gebunden ist, nennen wir es 'IsVisibile'. Die Sichtbarkeit ist die DP und die IsVisibile ist eine einfache Eigenschaft. Was normalerweise passiert, ist, wenn 'IsVisible' ändert, dass Sie die Benutzeroberfläche benachrichtigen wollen (meistens mit' INotifyPropertyChanged'), damit die 'DP' ihren Wert ändert, nicht umgekehrt ... –