绑定到接口绑定中未指定的属性

时间:2011-11-17 12:29:03

标签: wpf binding types interface

这里的标题有点模糊,我没有办法更清楚地说出来。

让我们以一个简单明了的例子说明我的情况:

首先:我有一个自定义控件FooControlDependencyProperty类型为IFoo。该控件应该在IFoo

中显示DataGrid个对象

请注意,当然,真实对象不只是显示一些值,我本可以只使用DataGrid来处理这个问题;)

public class FooControl : DataGrid
{
        /// <summary>
        /// Foo!
        /// </summary>
        public static readonly DependencyProperty FooProperty =
            DependencyProperty.Register("Foo",
                                        typeof(IFoo),
                                        typeof(FooControl),
                                        new PropertyMetadata(FooChanged));

第二:我有一个IFoo界面

public interface IFoo
{
    IList<double> Values { get; set; }
}

第三:我有Foo个对象,正在实施IFoo

public class Foo : IFoo
{
    public IList<double> Values { get; set; }
}

现在,我想要一个ObservableFoo,用于绑定更新目的,这里是:

public class ObservableFoo : Foo, INotifyCollectionChanged
{
    public ObservableCollection<double> ObservableValues {get; set; }
}

现在,问题:

我通常将FooControl绑定到Foo类型的对象,这些对象是IFoo接口的“严格”实现。 现在,我还需要有三个FooControl,它们应绑定到ObservableFoo类型的对象(显然是IFoo),但也要添加未在接口中指定的属性,即{ {1}})

ObservableValues类中,我手动设置绑定到要显示的值:

FooControl

/// <summary> /// Sets the binding on foo values /// </summary> /// <param name="propertyPath">Binding path</param> public void SetValuesBinding(string propertyPath) { // Binding for foovalues Binding fooBinding = new Binding(propertyPath); fooBinding.Converter = new FooConverter(); fooBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; fooBinding.RelativeSource = new RelativeSource(RelativeSourceMode.Self); fooBinding.Mode = BindingMode.TwoWay; this.SetBinding(FooControl.ItemsSourceProperty, fooBinding); } propertyPath时,它工作正常,更新绑定的目标会调用我为Foo.Values定义的PropertyChangedHandler

ItemsSourcepropertyPath时,更新绑定不会调用我定义的Foo.ObservableValues。但是,输出窗口上没有显示绑定错误!

在我对这个问题的理解中,它意味着:

  • 绑定“工作”,即。它找到了源属性
  • 但是,由于PropertyChangedHandler不在ObservableValues,而只在IFoo中,绑定会尝试查找ObservableFoo,而...无法更新。

我如何设法将绑定更新为IFoo.ObservableValues

我希望我能为你们清楚地说清楚。如果您需要我澄清,请随时提出任何问题

3 个答案:

答案 0 :(得分:1)

我认为问题在于您的约束力。

您绑定到RelativeSource Self,这意味着您的绑定正在阅读FooControl.Foo.ObservableValues,并且由于Foo被定义为IFooObservableValues属性不会存在。

一种可能的替代方法是将FooControl.DataContext设置为Foo,然后简单地ObservableValues进行绑定,这样只需调用DataContext.ObservableValues而不是FooControl.Foo.ObservableValues }

如果这不起作用,请尝试将ObservableValues属性放在IFoo上,或使Values属性成为可由IList或{继承的类型{1}},例如ObservableCollection

答案 1 :(得分:0)

mmm ...我不明白为什么你没有ObservableFoo实现INotifyCollectionChanged,INotifyPropertyChanged。

答案 2 :(得分:0)

好的,我终于找到了解决方法。

我在FooControl添加了一个属性:

    /// <summary>
    /// The values displayed
    /// </summary>
    public System.Collections.IEnumerable ValuesToDisplay
    {
        get
        {
            if (this.Foo is ObservableFoo)
            {
                return (this.Foo as ObservableFoo).ObservableValues;
            }
            else if (this.Foo == null)
            {
                return null;
            }
            else
            {
                return this.Foo.Values;
            }
        }
    }

我将嵌入的Datagrid的ItemSource绑定到此属性(使用指向自身的RelativeSource)并且...它工作正常。

但是,这仍然让我学到了一些东西:绑定不会在运行时解析类型,它只会显然采用指定的类型!