自定义WPF绑定

本文关键字:绑定 WPF 自定义 | 更新日期: 2023-09-27 18:00:06

我有一个模拟绑定的自定义MarkupExtension。它在正常分配中效果良好,但在样式设置器中使用时效果不佳,例如:

<Setter Property="Content" Value="{local:MyExtension}" />

导致XamlParseException:

A 'Binding' cannot be set on the 'Value' property of type 'Setter'.
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

这是扩展的实现:

public class MyExtension : MarkupExtension
{
    public MyExtension()
    {
        Value = 123;
    }
    public object Value
    {
        get;
        set;
    }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var binding = new Binding("Value")
        {
            Source = this,
        };
        return binding.ProvideValue(serviceProvider);
    }
}

怎么了?!

自定义WPF绑定

有点猜测,但这可能是因为XAML编译器对Binding类有特殊的内置支持,允许在这种情况下(以及其他情况下)使用它。Binding类也是MarkupExtension,但不幸的是,它封闭了ProvideValue()的实现。

也就是说,你可能会逃脱惩罚:

public class MyBinding : Binding
{
    private object value;
    public object Value
    {
        get { return this.value; }
        set
        {
            this.value = value;
            this.Source = value;
        }
    }
}

由于ProvideValue无论如何都会返回Binding实例。

从文档中看,对象必须是可冻结的(这样它们就可以在各个相关方之间共享)

http://msdn.microsoft.com/en-us/library/system.windows.setter.value.aspx

"如果指定的值是可冻结的对象,则支持对象内的数据绑定和动态资源。请参阅绑定标记扩展和动态资源标记扩展。"

你为什么不

return Value

ProvideValue内部??

其他

您只能绑定到DependencyProperty。在MyExtension类中为Value创建一个依赖属性!

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(Object), typeof(MyContentControl), new UIPropertyMetadata());