1

我正在尝试创建一个自定义图像控件,因为我必须根据某些事件来操纵它的源,而且我将拥有大量此类控件。为此,我决定从 Image 继承我的类(“nfImage”),并且我希望有一个 DP(它实际上会反映事件),我可以将它绑定到视图模型。我正在做:

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)));
            }
        }
    }
}

问题是它不起作用。如果我从后面的代码中设置 TagValue 的值,源代码会更改,但如果我从 xaml(通过 dp)设置它,则不会发生任何事情,绑定也不起作用。我如何做到这一点?

4

2 回答 2

2

您不能使用 setter,因为 XAML 不会直接调用它:它只是调用 SetValue(DependencyProperty, value) 而不通过您的 setter。您需要处理 PropertyChanged 事件:

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); }
    }
}
于 2013-02-11T22:08:04.083 回答
1

DependencyProperty 的包装器属性只是样板文件,除了 GetValue 和 SetValue 之外,它不应该做任何事情。这样做的原因是,在从代码直接调用属性包装器之外设置值的任何东西都不会使用包装器并直接调用 GetValue 和 SetValue。这包括 XAML 和绑定。您可以在 DP 声明中向元数据添加 PropertyChanged 回调,而不是包装器设置器,并在那里做额外的工作。任何 SetValue 调用都会调用它。

于 2013-02-11T22:09:30.150 回答