在XAML中填充Collection属性:Item DataContext为null

时间:2014-08-05 14:48:41

标签: wpf xaml binding

我的控件具有一个或多个键值对的ObservableCollection。这可以像往常一样(ObservableCollection绑定的ViewModel提供现成的Keys={Binding KeyCollection} - 它完美地工作),但我也希望能够在XAML中定义它:< / p>

<foo:KeyControl>
    <foo:KeyItem Key="ID" Value="{Binding ID}" />
    <foo:KeyItem Key="HatSize" Value="{Binding HatSize}" />
</foo:KeyControl>

KeyItem派生自FrameworkElement,属性KeyValue是依赖属性。我在ContentPropertyAttribute上有一个KeyControl,并且工作正常:填充了正确的集合属性,Key属性(具有文字值而不是绑定的属性)被初始化为在XAML中。

问题是Value属性的绑定不起作用。它们总是为属性赋值null。我认为那是因为KeyItem个实例的空DataContext

此外,RelativeSource FindAncestor认为没有任何祖先可以找到:

<foo:KeyItem Type="ID" 
    Value="{Binding Path=DataContext.ID, 
    RelativeSource={RelativeSource FindAncestor, AncestorType=foo:MyView}, 
    diag:PresentationTraceSources.TraceLevel=High}" /> 

当新的KeyItem实例添加到ObservableCollection时,我尝试将其DataContext设置为控件的DataContext,但控件的DataContext在该点始终为null(?!)if它们是在XAML中定义的。

我错过了什么?

更新

回答的内容是由Thomas Levesque在a linked article,所以如果离线,这是修复:你创建一个代理作为资源。在定义资源的位置,控件的DataContext在范围内。在集合项属性的绑定中,您可以访问该资源。

C#:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables 
    // animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), 
            typeof(BindingProxy), new UIPropertyMetadata(null));
}

XAML:

<foo:KeyControl>
    <foo:KeyControl.Resources>
        <foo:BindingProxy x:Key="proxy" Data="{Binding}" />
    </foo:KeyControl.Resources>

    <foo:KeyItem Key="ID" Value="{Binding Data.ID, 
        Source={StaticResource proxy}}" />
    <foo:KeyItem Key="HatSize" Value="{Binding Data.HatSize, 
        Source={StaticResource proxy}}" />
</foo:KeyControl>

有点像kludge,但它确实有效。不过,我想我可能会坚持使用ViewModels绑定集合。

出于搜索目的,当DataContexts为空时,我收到了“找不到框架导师”的错误。

1 个答案:

答案 0 :(得分:1)

我有一个类似的问题,datacontext没有继承,我使用这里描述的代理技术解决了我的问题 http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

希望这有帮助