基于本教程:
http://www.dotnetfunda.com/articles/article961-wpf-tutorial--dependency-property-.aspx
我已经像这样创建了我的usercontrol:
usercontrol xaml:
<UserControl x:Class="PLVS.Modules.Partner.Views.TestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tp="http://thirdparty.com/controls"
x:Name="UC">
<tp:ContainerControl x:Name="tpControl">
<tp:ContainerControl.Items>
<tp:SomeItem SomeProperty="SomeValue">
<TextBlock Text="SomeText"/>
</tp:SomeItem>
</ig:TabItemEx>
</tp:ContainerControl.Items>
</tp:ContainerControl>
</UserControl>
usercontrol代码隐藏:
public partial class TestControl : UserControl
{
public TestControl()
{
InitializeComponent();
SetValue(TestItemsPropertyKey, new ObservableCollection<ThirdPartyClass>());
}
public ObservableCollection<ThirdPartyClass> TestItems
{
get
{
return (ObservableCollection<ThirdPartyClass>)GetValue(TabItemsProperty);
}
}
public static readonly DependencyPropertyKey TestItemsPropertyKey =
DependencyProperty.RegisterReadOnly("TestItems", typeof(ObservableCollection<ThirdPartyClass>), typeof(TestControl), new UIPropertyMetadata(new ObservableCollection<ThirdPartyClass>(), TestItemsChangedCallback));
public static readonly DependencyProperty TestItemsProperty = TestItemsPropertyKey.DependencyProperty;
private static void TestItemsChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
TestControl ib = obj as TestControl;
var newNvalue = e.NewValue; // Why is e.NewValue null???
}
}
我想稍后使用这样的usercontrol:
<localControl:TestControl x:Name="testControl">
<localControl:TestControl.TabItems>
<tp:SomeItem SomeProperty="SomeValue">
<TextBlock Text="SomeText2"/>
</tp:SomeItem>
<tp:SomeItem SomeProperty="SomeValue">
<TextBlock Text="SomeText3"/>
</tp:SomeItem>
</tp:ContainerControl.Items>
</localControl:TestControl>
在上面的代码中,我在我的usercontrol中添加了一个回调函数,这样我就可以将新项添加到xaml中声明的容器控件“tpControl”中。但是,当触发回调函数时,新值为空。这里的问题是为什么?
答案 0 :(得分:0)
您实际上是将e.NewValue视为null还是空集合?
在您的代码中,您将属性的默认值设置为ObservableCollection实例(通常不应该对引用类型执行 - 只使用null),然后在控件的实例构造函数中指定ObservableCollection的另一个实例,这是触发Changed回调。此时您正在分配这个新的空集合,这是您应该看到的e.NewValue。
如果要访问XAML中声明的项目,则需要等到它们添加到集合中之后。添加项目不会导致属性的更改处理程序触发,因为您没有为DP分配新集合。您可以为稍后发生的其他事件(如已加载)使用处理程序
Loaded += (sender, e) => { DoSomething(TestItems) };
或将CollectionChanged处理程序附加到e.NewValue实例,每次添加,删除,移动项目时都会调用该实例。
var newValue = e.NewValue as ObservableCollection<ThirdPartyClass>;
newValue.CollectionChanged += (sender, args) => { DoSomething(TestItems); };