我想创建一组继承DependencyObject类的控件。 (对于这个故事,我不想在这些控件中进行测量/排列操作,但这不是重点。)
我天真地认为DependenciesProperties会直接处理这些控件。事实并非如此。
从概念上讲,由于我不更新DependencyObject的父级,显然DependencyProperties无法从父级中找到它们的值,因此不会继承DataContext等属性。
我找到了一半的解决方案:
using System;
using System.Reflection;
using System.Windows;
namespace ControlsLibrary.Base
{
public class FrameworkElement : DependencyObject
{
private static MethodInfo _setInheritanceParentMethod;
static FrameworkElement()
{
// NOTE: Hack to expose a hidden method.
_setInheritanceParentMethod = typeof(DependencyObject).GetMethod("SetInheritanceParent", BindingFlags.Instance | BindingFlags.NonPublic);
}
private delegate void SetInheritanceParentDelegate(DependencyObject obj);
private readonly SetInheritanceParentDelegate _setInheritanceParent;
private DependencyObject _inheritanceParent = null;
public FrameworkElement()
{
// NOTE: Prefer the use of delegates rather than MethodInfo.Invoke.
_setInheritanceParent = (SetInheritanceParentDelegate)Delegate.CreateDelegate(typeof(SetInheritanceParentDelegate), this, _setInheritanceParentMethod);
}
public DependencyObject InheritanceParent
{
get { return _inheritanceParent; }
set
{
if (_inheritanceParent != value)
{
_inheritanceParent = value;
_setInheritanceParent(_inheritanceParent);
}
}
}
public object DataContext
{
get { return (object)GetValue(DataContextProperty); }
set { SetValue(DataContextProperty, value); }
}
// Using a DependencyProperty as the backing store for DataContext. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataContextProperty =
System.Windows.FrameworkElement.DataContextProperty.AddOwner(typeof(FrameworkElement), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
}
}
使用该解决方案,我能够继承两个FrameworkElements之间的DataContext
var parent = new FrameworkElement();
var child = new FrameworkElement();
Assert.AreEqual(null, parent.DataContext);
Assert.AreEqual(null, child.DataContext);
parent.DataContext = "Test";
Assert.AreEqual("Test", parent.DataContext);
Assert.AreEqual(null, child.DataContext);
child.InheritanceParent = parent;
Assert.AreEqual("Test", parent.DataContext);
Assert.AreEqual("Test", child.DataContext);
parent.DataContext = "Check";
Assert.AreEqual("Check", parent.DataContext);
Assert.AreEqual("Check", child.DataContext);
child.DataContext = "Test";
Assert.AreEqual("Check", parent.DataContext);
Assert.AreEqual("Test", child.DataContext);
child.InheritanceParent = null;
Assert.AreEqual("Check", parent.DataContext);
Assert.AreEqual("Test", child.DataContext);
以及Wpf.FrameworkElement与我的一个FrameworkElement之间。
var parent = new System.Windows.FrameworkElement();
var child = new ControlsLibrary.Base.FrameworkElement();
大!
我尝试了三个FrameworkElements并且它不起作用...... DataContext继承了两个对象,但没有三个对象......
var element0 = new FrameworkElement();
var element1 = new FrameworkElement();
var element2 = new FrameworkElement();
element1.InheritanceParent = element0;
element2.InheritanceParent = element1;
Assert.AreEqual("Test", element0.DataContext);
Assert.AreEqual("Test", element1.DataContext); // --> This one works.
Assert.AreEqual("Test", element2.DataContext); // --> But this one is null!!!
所以我猜我做错了。
所以问题是:如何继承DependencyObject类并使DependencyProperties工作?
换句话说:有人已经“入侵”了DependencyObject类吗?有人可以提供一个完整的解释,说明我必须做些什么才能拥有一个功能齐全的FrameworkElement?
还是死了?
如果有必要,我可以帮助其他人了解它是如何运作的!
谢谢!