Taras
Taras

Reputation: 1128

add a dependency property to class inherited from control?

I'm trying to create a custom Image control, because I have to manipulate it's sources depending on some events, also i will have pretty large array of such controls. To do that i decided my class ("nfImage") to be inherited from Image, and i want there a DP (which actually would reflect the events) to I could bind it to a view-model. I'm doing:

class nfImage : Image
{
    public static readonly DependencyProperty TagValueProperty =
        DependencyProperty.Register("TagValue", typeof(int), typeof(nfImage), new UIPropertyMetadata(0));

    public int TagValue
    {
        get { return (int)GetValue(TagValueProperty); }
        set
        {
            SetValue(TagValueProperty, value);
            if (this.Source != null)
            {
                string uri = (this.Source.ToString()).Substring(0, (this.Source.ToString()).Length - 5) + value.ToString() + ".gif";
                ImageBehavior.SetAnimatedSource(this, new BitmapImage(new Uri(uri, UriKind.Absolute)));
            }
        }
    }
}

the problem is it doesn't work. If I'm setting the value of TagValue from code behind, source changes, but if I'm setting it from xaml (through the dp) nothing happens, bindings don't work also. How do I achive this?

Upvotes: 1

Views: 716

Answers (2)

John Bowen
John Bowen

Reputation: 24453

The wrapper property for a DependencyProperty is just boilerplate that should never do anything but GetValue and SetValue. The reason for this is that anything setting the value outside of direct calls to the property wrapper from code don't use the wrapper and call GetValue and SetValue directly. This includes XAML and Bindings. Instead of the wrapper setter, you can add a PropertyChanged callback to the Metadata in your DP declaration and do your extra work there. This is called for any SetValue call.

Upvotes: 1

Shlomo
Shlomo

Reputation: 14370

You can't use the setter, since XAML doesn't call it directly: It just calls SetValue(DependencyProperty, value) without going through your setter. You need to handle a PropertyChanged Event:

class nfImage : Image
{

    public static readonly DependencyProperty TagValueProperty =
        DependencyProperty.Register("TagValue", typeof(int), typeof(nfImage), new UIPropertyMetadata(0, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var _this = dependencyObject as nfImage;
        var newValue = dependencyPropertyChangedEventArgs.NewValue;
        if (_this.Source != null)
        {
            string uri = (_this.Source.ToString()).Substring(0, (_this.Source.ToString()).Length - 5) + newValue.ToString() + ".gif";
            //ImageBehavior.SetAnimatedSource(this, new BitmapImage(new Uri(uri, UriKind.Absolute)));
        }
    }

    public int TagValue
    {
        get { return (int)GetValue(TagValueProperty); }
        set { SetValue(TagValueProperty, value); }
    }
}

Upvotes: 2

Related Questions