I would like to extend FrameworkElement
elements like the Button
class by collection-type attached property that collect DependencyObjects
.
The difficulty is that the bindings to the collection items do not work: No debug nor runtime error shows up but the bound source gets never called.
I noted that the collection-type attached property does not inherit from class DependencyObject
.
I guess the DataContext
property will be inherited by any child DependencyObject
object (as long as the parent is also a DependencyObject
object). As the collection-type attached property does not inherit from DependencyObject
the DataContext
property inheritance does not occur.
- I wonder why instances of
DependencyObject
can inherit theDataContext
property asDataContext
is a property defined inFrameworkElement
? How does theDependencyObject
manage theDataContext
lookup? - Why does specifying the binding source with
ElementName=PageName
not work as well (e.g.{Binding MyProperty="{Binding DataContext.PropertySource1, ElementName=PageName}
)? If theDependencyObject
is also responsible forElementName
lookups, how does it do it? - Is there a UWP collection that inherits
DependencyObject
? (In WPF there isFreezableCollection<T>
class but I couldn't find a pendant in the UWP environment.)
The XAML markup below shows an example extension, where the Binding
does not work.
<Button Name="Button">
<ext:MyExtension.MyCollection>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
</ext:MyExtension.MyCollection>
</Button>
If I do the following extension for non-collection-type attached properties the binding can be resolved correctly.
<Button Name="Button">
<ext:MyExtension.MyProperty>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
</ext:MyExtension.MyProperty>
</Button>
The code below shows a sample collection-type attached property implementation. Consider the attached property class also contains a definition for a non-colleciton-type attached property (which works correctly with binding).
public class MyDependencyObject: DependencyObject
{
public object MyProperty
{
get { return (object)GetValue(MyPropertyProperty ); }
set { SetValue(MyPropertyProperty , value); }
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("MyProperty", typeof(object), typeof(MyProperty), null);
}
public class MyPropertyCollection : ObservableCollection<MyDependencyObject> { }
public static class MyExtension
{
// Collection-type AttachedProperty with DependencyObject items
public static MyPropertyCollection GetMyPropertyCollection(DependencyObject obj)
{
MyPropertyCollection collection = (MyPropertyCollection )obj.GetValue(MyCollectionProperty );
if (collection == null)
{
collection = new MyPropertyCollection();
collection.CollectionChanged +=
(sender, e) =>
{
//intiailization of elements possible
};
obj.SetValue(MappingsProperty, collection);
}
return collection;
}
public static void SetMyPropertyCollection(DependencyObject obj, MyPropertyCollection value)
{
obj.SetValue(MyCollectionProperty , value);
}
public static readonly DependencyProperty MyCollectionProperty =
DependencyProperty.RegisterAttached("MyCollection", typeof(MyPropertyCollection), typeof(MyExtension), null);
// DependencyObject-type AttachedProperty
public static MyProperty GetMapping(DependencyObject obj)
{
return (MyProperty )obj.GetValue(MyPropertyProperty );
}
public static void SetMapping(DependencyObject obj, MyProperty value)
{
obj.SetValue(MyPropertyProperty , value);
}
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.RegisterAttached("MyProperty", typeof(MyDependencyObject), typeof(MyExtension), null);
}