我想通过收集FrameworkElement
的集合类型附加属性扩展Button
类DependencyObjects
类。
难点在于对集合项的绑定不起作用:没有显示调试或运行时错误,但从未调用绑定源。
我注意到集合类型附加属性不继承自类DependencyObject
。
我想DataContext
属性将由任何子DependencyObject
对象继承(只要父对象也是DependencyObject
对象)。由于collection-type附加属性不从DependencyObject
继承,因此DataContext
属性继承不会发生。
DependencyObject
的实例可以继承DataContext
属性,因为DataContext
是FrameworkElement
中定义的属性? DependencyObject
如何管理DataContext
查找?ElementName=PageName
的绑定源不起作用(例如{Binding MyProperty="{Binding DataContext.PropertySource1, ElementName=PageName}
)?如果DependencyObject
也负责ElementName
查询,它是如何做到的?DependencyObject
的UWP集合? (在WPF中有FreezableCollection<T>
类但我在UWP环境中找不到吊坠。)下面的XAML标记显示了一个示例扩展,其中Binding
不起作用。
<Button Name="Button">
<ext:MyExtension.MyCollection>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
</ext:MyExtension.MyCollection>
</Button>
如果我对非集合类型附加属性执行以下扩展,则可以正确解析绑定。
<Button Name="Button">
<ext:MyExtension.MyProperty>
<ext:MyDependencyObject MyProperty="{Binding PropertySource1}"/>
</ext:MyExtension.MyProperty>
</Button>
下面的代码显示了一个示例集合类型附加属性实现。考虑附加属性类还包含非colleciton类型附加属性的定义(它可以正确地绑定)。
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);
}
答案 0 :(得分:2)
在WPF中,可以使用FreezableCollection<T>
或继承Freezable
类,IList<T>
和IList
:
DependencyObject
继承它,因为无法访问DependencyObject
的两个必需方法,但Freezable
有一个包装器。IList<T>
和IList
。OnFreezablePropertyChanged(null, newItem)
。OnFreezablePropertyChanged(item, null)
。 OnFreezablePropertyChanged
方法在内部将调用两个DependencyObject
方法来提供或删除继承上下文(source)。
但是在UWP中没有Freezable
并且没有这样的方法,所以在Windows 10.0.10240.0之前它是不可能的。但是,如果您的目标是v10.0.10240.0或更高版本,则应使用针对行为制作的DependencyObjectCollection
。
DependencyObjectCollection类的目的主要是支持行为的工具和可移植性。行为是一种完全在XAML中定义UI元素的某些基本交互的技术,无需事件处理程序和代码隐藏。
因此,在UWP和WPF中,只有当子节点是逻辑/可视子节点或它们是依赖属性值时,才能为子节点提供继承上下文。因此,Binding
设置ElementName
在您的案例中使用时不起作用。当绑定附加到依赖项对象而非编译时,ElementName
属性用于在运行时解析对象。
UWP绑定的工作方式与WPF绑定类似,例如,请参阅第二个平台的ElementObjectRef.GetObject
。