Wpf CollectionType依赖属性

Wpf CollectionType依赖属性,wpf,user-controls,dependency-properties,Wpf,User Controls,Dependency Properties,基于本教程: 我创建的usercontrol如下所示: <localControl:TestControl x:Name="testControl"> <localControl:TestControl.TabItems> <tp:SomeItem SomeProperty="SomeValue"> <TextBlock Text="SomeText2"/> </tp:SomeItem>

基于本教程:

我创建的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>
用户控制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> 
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 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> 
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???
 }
 }
public部分类TestControl:UserControl
{
公共测试控制()
{
初始化组件();
SetValue(TestItemsPropertyKey,新的ObservableCollection());
}
公众可观察收集测试
{
得到
{ 
返回(ObservableCollection)GetValue(TabItemsProperty);
}
}
公共静态只读依赖项PropertyKey TestItemsPropertyKey=
DependencyProperty.RegisterReadOnly(“TestItems”、typeof(ObservableCollection)、typeof(TestControl)、new-UIPropertyMetadata(new-ObservableCollection()、TestItemsChangedCallback));
公共静态只读DependencyProperty TestItemsProperty=TestItemsPropertyKey.DependencyProperty;
私有静态void TestItemsChangedCallback(DependencyObject对象,DependencyPropertyChangedEventArgs e)
{
TestControl ib=obj作为TestControl;
var newNvalue=e.NewValue;//为什么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”中。但是,当触发回调函数时,新值为空。这里的问题是为什么?

您实际上是将e.NewValue视为null还是一个空集合

在代码中,您将属性的默认值设置为ObservaleCollection实例(对于引用类型,您通常不应该这样做-只需使用null),然后在控件的实例构造函数中分配ObservaleCollection的另一个实例,这将触发已更改的回调。此时,您正在分配这个新的空集合,这是您应该看到的e.NewValue

如果要访问在XAML中声明的项,需要等到它们被添加到集合中之后。添加这些项不会导致触发属性的更改处理程序,因为您没有将新集合分配给DP。您可以为以后发生的不同事件(如Loaded)使用处理程序

或者将CollectionChanged处理程序附加到e.NewValue实例,该实例将在每次添加、删除、移动项时调用

    var newValue = e.NewValue as ObservableCollection<ThirdPartyClass>;
    newValue.CollectionChanged += (sender, args) => { DoSomething(TestItems); };
var newValue=e.newValue作为可观测集合;
newValue.CollectionChanged+=(发送方,参数)=>{DoSomething(TestItems);};