2010-08-11 35 views
0

基於此教程CollectionType依賴項屬性

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> 

在上面的代碼中,我在我的用戶增加了一個回調函數,這樣我可以添加新的項目到容器控件「 tpControl「在xaml中聲明。但是,當回調函數被觸發時,新值爲空。這裏的問題是爲什麼?

回答

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); };