2010-08-11 4 views
0

Sur la base de ce tutoriel:CollectionType Dépendance Propriété

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

J'ai créé mon usercontrol comme ceci:

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 code-behind :

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??? 
} 
} 

Je veux utiliser plus tard usercontrol comme ceci:

<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> 

Dans le code ci-dessus j'ai ajouté une fonction de rappel dans mon usercontrol afin que je puisse ajouter les nouveaux éléments au contrôle des conteneurs " tpControl "déclaré dans le xaml. Cependant, lorsque la fonction de rappel est déclenchée, la nouvelle valeur est vide. Et la question ici est pourquoi?

Répondre

0

Est-ce que vous voyez réellement e.NewValue comme nul ou comme une collection vide?

Dans votre code, vous définissez une valeur par défaut pour la propriété sur une instance ObservableCollection (ce que vous ne devriez généralement pas faire pour les types de référence - utilisez null), puis attribuez une autre instance de ObservableCollection au constructeur d'instance de votre contrôle. , qui déclenche le rappel modifié. À ce stade, vous affectez maintenant cette nouvelle collection vide, ce que vous devriez voir pour e.NewValue.

Si vous souhaitez accéder aux éléments déclarés en XAML, vous devez attendre qu'ils aient été ajoutés à la collection. L'ajout des éléments ne provoque pas le déclenchement du gestionnaire de changement pour la propriété, car vous n'attribuez pas de nouvelle collection au DP. Vous pouvez utiliser un gestionnaire pour un événement différent qui se produit plus tard (comme Loaded)

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

ou joindre un gestionnaire CollectionChanged à l'instance e.NewValue qui sera appelée à chaque fois qu'un élément est ajouté, enlevé, déplacé, etc.

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