【问题标题】:CollectionType Dependency PropertyCollectionType 依赖属性
【发布时间】:2011-05-07 20:20:36
【问题描述】:

根据本教程:

http://www.dotnetfunda.com/articles/article961-wpf-tutorial--dependency-property-.aspx

我已经像这样创建了我的用户控件:

用户控件 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???
 }
 }

我想以后像这样使用用户控件:

 <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 中声明的容器控件“tpControl”中。但是,当触发回调函数时,新值是空的。而这里的问题是为什么?

【问题讨论】:

    标签: wpf user-controls dependency-properties


    【解决方案1】:

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

    在您的代码中,您将属性的默认值设置为 ObservableCollection 实例(通常不应为引用类型执行此操作 - 只需使用 null),然后在控件的实例构造函数中分配 ObservableCollection 的另一个实例,这触发了 Changed 回调。此时,您现在正在分配这个新的空集合,这就是您应该看到的 e.NewValue。

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

        Loaded += (sender, e) => { DoSomething(TestItems) };
    

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

        var newValue = e.NewValue as ObservableCollection<ThirdPartyClass>;
        newValue.CollectionChanged += (sender, args) => { DoSomething(TestItems); };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      • 2015-04-23
      • 2014-05-23
      • 2015-04-25
      相关资源
      最近更新 更多