【发布时间】:2012-10-22 07:38:47
【问题描述】:
如果我创建一个这样的自定义控件:
public class MyControl : ContentControl
{
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
"Items",
typeof(ObservableCollection<object>),
typeof(MyControl),
new PropertyMetadata(null));
public MyControl()
{
// Setup a default value to empty collection
// so users of MyControl can call MyControl.Items.Add()
Items = new ObservableCollection<object>();
}
public ObservableCollection<object> Items
{
get { return (ObservableCollection<object>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
}
然后允许用户像这样在 Xaml 中绑定到它:
<DataTemplate>
<MyControl Items="{Binding ItemsOnViewModel}"/>
</DataTemplate>
那么绑定永远不会起作用!这是由于Dependency Property Precedence 将CLR Set 值置于模板绑定之上!
所以,我明白为什么这不起作用,但我想知道是否有解决方案。是否可以为只想以编程方式添加项目的 MyControl 的懒惰消费者提供新的 ObservableCollection 的 ItemsProperty 的默认值,同时允许 My Control 的 MVVM 高级用户通过 DataTemplate 绑定到相同的属性?
这适用于 Silverlight 和 WPF。样式中的 DynamicResource 设置器似乎是一个解决方案,但这不适用于 Silverlight :(
更新:
我可以确认 SetCurrentValue(ItemsProperty, new ObservableCollection<object>()); 完全符合我的要求 - 在 WPF 中。它写入默认值,但它可以被模板绑定覆盖。 谁能推荐一个等效的 Silverlight? 说起来容易做起来难! :s
另一个更新:
显然,您可以使用值强制在 .NET3.5 中模拟 SetCurrentValue,并且可以使用这些技术在 Silverlight 中模拟值强制。也许这里有一个(冗长的)解决方法。
SetCurrentValue workaround for .NET3.5 using Value Coercion
Value Coercion workaround for Silverlight
【问题讨论】:
-
您可以在构造函数中调用
SetCurrentValue(ItemsProperty, new ObservableCollection<object>());而不是Items = new ObservableCollection<object>();。但这也只适用于 WPF,不适用于 Silverlight。 -
谢谢,我们正在取得进展。为银光感到羞耻!另一种解决方案是将默认 via 样式设置为 DynamicResource。同样,没有银光:S
-
您是否可以存储原始绑定,例如 var x = this.GetBindingExpression(ItemsProperty).ParentBinding;然后将项目设置为默认值,然后将绑定重置为原来的? this.SetBinding(ItemsProperty, x);不确定它会重置到什么级别 - 所以也许这可以工作?
-
有可能——我在 StackOverflow 中搜索了 SetCurrentValue() silverlight 并找到了另一篇帖子,没有代码解决方案,但他们确实谈到了一些奇怪的绑定黑客来实现这一点。太可惜了,似乎没有本地方法可以做到这一点!
-
它适用于 Silverlight。你有测试用例吗?
标签: wpf silverlight xaml dependency-properties