简体   繁体   English

“Binding”类型的DependencyProperty未更新

[英]DependencyProperty of type “Binding” is not being updated

I'm having trouble creating a DependencyProperty of type "Binding". 我在创建“Binding”类型的DependencyProperty时遇到了麻烦。 Other types work ok, and they resolve successfully if I populate them using a binding. 其他类型工作正常,如果我使用绑定填充它们,它们会成功解析。

In my scenario I want to grab the raw binding, so that I can use it to bind to properties of child objects, in much the same way that DataGrid does columns - ie for each binding specified in a column, it binds to each of the items in the ItemsSource collection, rather than binding the the DataContext itself. 在我的场景中,我想获取原始绑定,以便我可以使用它来绑定到子对象的属性,就像DataGrid列的相同 - 即对于列中指定的每个绑定,它绑定到每个ItemsSource集合中的项目,而不是绑定DataContext本身。

<mg:MultiSelectDataGrid x:Name="Grid" DockPanel.Dock="Left" 
     ItemsSource="{Binding Path=Rows}" DataContext="{Binding}" 
     AutoGenerateColumns="False" UriBinding="{Binding Path=UrlItems}">

And in my "MultiSelectDataGrid": 在我的“MultiSelectDataGrid”中:

    public static readonly DependencyProperty UriBindingProperty = 
       DependencyProperty.Register("UriBinding", typeof(BindingBase),
           typeof(MultiSelectDataGrid), 
           new PropertyMetadata { PropertyChangedCallback = OnBindingChanged});


    private static void OnBindingChanged(DependencyObject d,
                            DependencyPropertyChangedEventArgs e)
    {
         // This is never enterred
    }


    public BindingBase UriBinding
    {
        get { return (BindingBase)GetValue(UriBindingProperty); }
        set { SetValue(UriBindingProperty, value); }
    }

The callback never gets called, and the property never gets set. 永远不会调用回调,并且永远不会设置属性。 I've tried all kinds of permutations, with callbacks, without. 我已经尝试过各种各样的排列,没有回调。 The only thing that gave me any success was if I replaced the binding with a string (eg UriBinding="hello") - in that case it would fire the callback, and set the property, but would, of course, fail because it's the wrong type. 唯一让我取得成功的是如果我用字符串替换绑定(例如UriBinding =“hello”) - 在这种情况下它会触发回调,并设置属性,但当然会失败,因为它是错误的类型。

What am I doing wrong? 我究竟做错了什么? I've seen a whole load of examples of this, and I guess this is what DataGrid must be doing itself. 我已经看到了一大堆这样的例子,我想这就是DataGrid必须做的事情。

Thanks 谢谢

Curiously only other place I am aware of that has Binding type property is DataGridBoundColumn class which derives into DataGridTextColumn , DataGridCheckBoxColumn etc... 奇怪的是,我所知道的其他具有Binding类型属性的地方是DataGridBoundColumn类,它派生到DataGridTextColumnDataGridCheckBoxColumn等......

And interestingly there the property is NOT a dependency property. 有趣的是,该属性不是依赖属性。 It is a plain CLR type property. 它是一个普通的CLR类型属性。 I guess the infrastructre of binding is based upon the limitation that you cannot bind to binding type DP. 我想绑定的基础结构是基于你无法绑定到绑定类型DP的限制。

Other properties of the same class are very well DPs like Visibility, Header etc. 同一类的其他属性非常好,如可见性,标题等。

In DataGridBoundColumn the Binding property is declared as below with a very crude explanation for the same ... DataGridBoundColumnBinding属性声明如下,并给出了相同的粗略解释......

This isn't a DP because if it were getting the value would evaluate the binding. 这不是DP,因为如果它获得该值将评估绑定。

    /// <summary>
    ///     The binding that will be applied to the generated element.
    /// </summary>
    /// <remarks>
    ///     This isn't a DP because if it were getting the value would evaluate the binding.
    /// </remarks>
    public virtual BindingBase Binding
    {
        get
        {
            if (!_bindingEnsured)
            {
                if (!IsReadOnly)
                {
                    DataGridHelper.EnsureTwoWayIfNotOneWay(_binding);
                }

                _bindingEnsured = true;
            }

            return _binding;
        }

        set
        {
            if (_binding != value)
            {
                BindingBase oldBinding = _binding;
                _binding = value;
                CoerceValue(IsReadOnlyProperty);
                CoerceValue(SortMemberPathProperty);
                _bindingEnsured = false;
                OnBindingChanged(oldBinding, _binding);
            }
        }
    }

While @WPF-it solution works, it's unsuitable for attached properties, since you can't attach CLR properties. 虽然@ WPF-it解决方案有效,但它不适用于附加属性,因为您无法附加CLR属性。 To solve this you can define your attached property as usual, and get the binding object by calling BindingOperations.GetBindingBase() . 要解决此问题,您可以照常定义附加属性,并通过调用BindingOperations.GetBindingBase()获取绑定对象。

private static void OnMyPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // Can also use GetBinding(), GetBindingExpression()
    // GetBindingExpressionBase() as needed.
    var binding = BindingOperations.GetBindingBase(d, e.Property);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM