【发布时间】:2017-02-07 11:29:35
【问题描述】:
尝试重构一个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) 这是因为它们不是该类型的静态成员。
这是我的问题:这样做是否OK?
我担心的是内存(即泄漏)和性能。如果确认没问题,我可能会开始大量使用这种技术。
可能听起来像是基于意见,但我怀疑能否单独正确测试。
编辑,这里是创建和检索此类属性的 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.:尝试创建具有相同名称的依赖属性会抛出异常。所以应该有办法访问它。
【问题讨论】:
-
您引用的两个问题都显示了如何检索依赖项属性值,那么这是怎么回事?
-
@Evk,见编辑。
-
除非您打算动态创建新类型(发射?),否则 IMO 唯一要做的就是自己跟踪这些属性
-
@AdrianoRepetti,如果无法按名称检索属性(所以我必须存储参考,而不是名称),我的问题仍然是:可以这样做吗?我不创建静态成员或 Get/Set
Property方法(仅 xaml afaik 需要这些),它不会产生一些问题吗?有些东西不会被释放,等等?一些收藏品会不断增长而从未清理过? -
AFAIK 没关系(当然……除非您一直添加属性直到内存不足……如果您添加的属性是临时的,那么它们需要注销。)我记得我看到有人尝试类似的方法
标签: c# wpf attached-properties