尝试重构一个tedious solution,我已经辉煌想法动态创建附加属性,基本上:
void SomeMethod()
{
...
var dp = DependencyProperty.RegisterAttached("SomeUniqueOrGeneratedName333", typeof(object), typeof(CurrentClass));
...
}
这不是recommended方式。
我正在使用这些属性(非常惊讶,就像有人使用附加属性做其他事情一样)作为一些与对象数据相关的存储(即绑定)。稍后在同一方法的lambda中检索它们(不确定它是如何调用的, closure 我能想到的最接近的单词),例如:
// create attached property an store binding to retrieve result later
var dp = DependencyProperty.RegisterAttached("LolBinding", typeof(object), typeof(CurrentClass));
BindingOperations.SetBinding(obj, dp, someBinding);
// another ap and binding, this time with event (will trigger when DataContext for obj is set)
BindingOperations.SetBinding(obj, DependencyProperty.RegisterAttached("LolAnotherBinding", typeof(object), typeof(CurrentClass), new PropertyMetadata(null, (d, e) =>
{
var value = obj.GetValue(dp); // accessing ap
if (value != null) { ... } // do something
})), Property);
这很有效。我可以附加任意数量的属性:
for(int i = 0; i < 10000; i++)
DependencyProperty.RegisterAttached("SomeName" + i, typeof(object), typeof(MainWindow));
但它有问题,因为retrieve dependency property(也不是via reflection)是不可能的。我的猜测(feel free to discover)因为那些不是该类型的静态成员。
我担心的是记忆(即泄漏)和表现。如果确认没问题,我可能会开始使用这种技术。
可能听起来像基于意见,但我怀疑是否能够单独正确地测试它。
编辑,这里是mcve来创建和检索这样的属性:
// put this into window constructor
var dp = DependencyProperty.RegisterAttached("SomeName", typeof(object), typeof(MainWindow));
SetValue(dp, "test"); // even trying to set value
// trying to access it by name
var a = DependencyPropertyDescriptor.FromName("SomeName", typeof(MainWindow), typeof(MainWindow), true);
var b = GetAttachedProperty(this, "SomeName", typeof(MainWindow)); // method from linked question
a
和b
都是null
。我只能通过传递参考来访问dp
。
P.S。:尝试创建具有相同名称的依赖项属性将抛出。所以应该有办法访问它。
答案 0 :(得分:1)
我明白你的意思了。是的,DependencyPropertyDescriptor.FromName
对您的情况没有帮助,因为您没有在目标类型上定义GetValue和SetValue方法。但是,有一种方法可以通过一些反射来获取您的依赖项属性。需要反思,因为这个有用的方法(DependencyProperty.FromName
)出于内部的一些奇怪的原因:
// put this into window constructor
var dp = DependencyProperty.RegisterAttached("SomeName", typeof(object), typeof(MainWindow));
SetValue(dp, "test"); // even trying to set value
// do this only once per application
var fromNameMethod = typeof(DependencyProperty).GetMethod("FromName", BindingFlags.Static | BindingFlags.NonPublic);
var fromName = (Func<string, Type, DependencyProperty>) fromNameMethod.CreateDelegate(typeof(Func<string, Type, DependencyProperty>));
// now it's fast to call this method via delegate, almost 0 reflection costs
var a = fromName("SomeName", typeof(MainWindow));
var value = GetValue(a); // "test"
至于可以使用它。当然,这可能不是附加属性的预期用法,但我认为没有问题。依赖属性值存储在对象本身中,而不是存储在某个静态位置,因此一旦收集了对象本身,它们就会被收集。当然,在您注册后,附加属性本身不会被收集,但除非您注册太多,否则这不应该是一个问题。