11 votes

Obtention du pointeur 'this' dans le callback de modification de la propriété de la dépendance

J'ai la propriété de dépendance suivante à l'intérieur d'une classe :

class FooHolder
{
    public static DependencyProperty CurrentFooProperty = DependencyProperty.Register(
        "CurrentFoo",
        typeof(Foo), 
        typeof(FooHandler),
        new PropertyMetadata(OnCurrentFooChanged));

    private static void OnCurrentFooChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FooHolder holder = (FooHolder) d.Property.Owner; // <- something like this

        // do stuff with holder
    }
}

Je dois pouvoir récupérer une référence à l'instance de classe à laquelle appartient la propriété modifiée.

En effet, le FooHolder possède des gestionnaires d'événements qui doivent être connectés/déconnectés lorsque la valeur de la propriété est modifiée. Le rappel de changement de propriété doit être statique, mais le gestionnaire d'événements ne l'est pas.

17voto

Catalin DICU Points 2785

Quelque chose comme ceci : (vous devrez définir UnwireFoo() et WireFoo() vous-même)

private static void OnCurrentFooChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    FooHolder holder = (FooHolder)d; // <- something like this

    holder.UnwireFoo(e.OldValue as Foo);
    holder.WireFoo(e.NewValue as Foo);
}

Et, bien sûr, FooHolder doit hériter de DependencyObject

3voto

Thomas Levesque Points 141081

Le propriétaire du bien à modifier est le d de votre méthode de rappel

3voto

hypehuman Points 225

En me basant sur la réponse de @catalin-dicu, j'ai ajouté cette méthode d'aide à ma bibliothèque. Il m'a semblé un peu plus naturel d'avoir la méthode OnChanged non statique et de cacher tout le casting.

static class WpfUtils
{
    public static DependencyProperty RegisterDependencyPropertyWithCallback<TObject, TProperty>(string propertyName, Func<TObject, Action<TProperty, TProperty>> getOnChanged)
        where TObject : DependencyObject
    {
        return DependencyProperty.Register(
            propertyName,
            typeof(TProperty),
            typeof(TObject),
            new PropertyMetadata(new PropertyChangedCallback((d, e) =>
                getOnChanged((TObject)d)((TProperty)e.OldValue, (TProperty)e.NewValue)
            ))
        );
    }
}

Exemple d'utilisation :

class FooHolder
{
    public static DependencyProperty CurrentFooProperty = WpfUtils.RegisterDependencyPropertyWithCallback
        <FooHolder, Foo>("CurrentFoo", x => x.OnCurrentFooChanged);

    private void OnCurrentFooChanged(Foo oldFoo, Foo newFoo)
    {
        // do stuff with holder
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X