WinRT DependencyProperty with IEnumerable not firing at all

懵懂的女人 提交于 2019-12-01 17:59:53

I would try checking if the binding ever fires with a DebugConverter - check the BindingDebugConverter in the WinRT XAML Toolkit - set it as a converter for your binding and see if and when it breaks (is it in Convert or ConvertBack, what value is being set etc.).

If that does not help - check if your DataContext is set correctly.

*EDIT 1

If what you are looking is changes in the items of the bound collection - you can check if ItemsSource is an INotifyCollectionChanged and if true - subscribe to the CollectionChanged event to see the changes. Otherwise - you could modify your control to inherit from ItemsControl and override methods like GetContainerForItemOverride and IsItemItsOwnContainerOverride.

*EDIT 2

It seems like there is a bug in the framework in Windows 8 Consumer Preview related to using IEnumerable as the type of a dependency property. Using object as the type solves the problem. If you enable native code debugging you will see this binding exception:

Error: Converter failed to convert value of type 'System.Collections.ObjectModel.ObservableCollection`1[[ACBDP.Person, ACBDP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' to type 'IEnumerable'; BindingExpression: Path='Persons' DataItem='ACBDP.BlankPageViewModel, ACBDP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'ACBDP.AutoCompleteBox' (Name='null'); target property is 'ItemsSource' (type 'IEnumerable').

There are 2 quick solutions

(Here BaseClass is for example an abstract class or an interface that you derive from and instances of which you are trying to bind to a dependency property)

Solution 1:

You need to change typeof(BaseClass) to typeof(object) when registering a dependency property. Getter and setter may continue use your BaseClass, but be aware of InvalidCastException if you set a different type instance to this dependency property.

        public BaseClass Item
        {
            get { return (BaseClass)GetValue(ItemProperty); }
            set { SetValue(ItemProperty, value); }
        }
        public static readonly DependencyProperty ItemProperty =
            DependencyProperty.Register("Item", typeof(object), typeof(MyUserControl), new PropertyMetadata(null));

Solution 2:

Create a dummy dependency property somewhere in your code (for example right after the dependency property you are trying to create) that will have a type of all your derived types. Like this:

#region DummyProperty

public DerivedClass1 Dummy
{
    get { return (DerivedClass1)GetValue(DummyProperty); }
    set { SetValue(DummyProperty, value); }
}

public static readonly DependencyProperty DummyProperty =
    DependencyProperty.Register("Dummy", typeof(DerivedClass1), typeof(MyUserControl), new PropertyMetadata(default(DerivedClass1)));

#endregion

Here DerivedClass1 is derived from BaseClass.

Why?

I suppose the reason is that XAML doesn't know anything about your derived types and only knows about the BaseClass. So creating a dummy dependency property for each type should solve the problem.

Change typeof(IEnumerable) to typeof(object)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!