2009-10-15 3 views
3

Je me demandais si dans WPF vous pouviez obtenir les instances réelles des objets datatemplate. Par exemple, dans la situation suivante:Accès aux éléments à l'intérieur du DataTemplate dans WPF

<UserControl> 
    <UserControl.Resources> 
     <DataTemplate x:Key="MyTemplate"> 
      <CustomControl ></CustomControl> 
     </DataTemplate> 
    </UserControl.Resources> 

    <ListBox DataTemplate="{StaticResource MyTemplate}"></ListBox> 
</UserControl> 

Supposons que CustomControl a un CustomEvent et un CustomMethod public. Je veux accéder à cet événement et la méthode publique dans le contrôle de l'utilisateur. Est-ce possible? Comment serais-je capable de faire ça? Merci d'avance pour votre aide.

Cheers,

Nilu

+0

les accès d'où? – itowlson

+0

@itowlson: à partir du contrôle UserControl dans lequel ListBox est placé. Je souhaite appeler une méthode personnalisée (contenue dans CustomControl) à partir du contrôle usercontrol lorsque l'événement se déclenche. – Nilu

Répondre

0

Vous pouvez créer un objet qui se fixe au CustomControl et interagit avec elle.

Ce blogpost illustré ici quelques concepts utiles que nous pouvons étendre sur: ICommand for Silverlight with Attached Behaviors

Ainsi, au lieu de se fixer à l'événement de clic d'un bouton (qui WPF a déjà une commande de toute façon), vous pouvez créer une classe qui attache à votre contrôle personnalisé.

Suivant le modèle dans le billet de blog référencé vous finiriez avec:

<CustomControl 
    MyNamespace:CustomControlCommand.EventCommand= 
    "{Binding Path=CommandHandler}" /> 

Cela vous donnera accès aux événements de la CustomControl en les transformant en commandes.

5

Vous devez trouver le ContentPresenter tenant ListBox (en naviguant sur le VisualTree) puis utilisez

myDataTemplate.FindName("myCustomControl", myListBox); 

Il est un exemple sur MSDN: http://msdn.microsoft.com/en-us/library/bb613579.aspx.

+0

En passant par le VisualTree comme le plus souvent pas ce que vous voulez et de meilleures solutions existent pour ce cas –

+0

J'ai répondu à la question "[comment] obtenir les instances réelles des objets datatemplate." L'en-tête de la question est "Accéder aux éléments à l'intérieur du DataTemplate dans WPF", après tout. Pour autant que je puisse voir, c'est la façon standard de le faire. – hwiechers

+0

Voter pour cette réponse, car c'était la réponse que je cherchais lorsque j'ai trouvé cette question. Ce n'est peut-être pas le meilleur moyen, et il est bon d'offrir des solutions de rechange, mais ce n'est pas une raison pour refuser ce qui est clairement la bonne réponse à la question posée. – Niall

0

Je ne vois pas la liaison de données ItemsSource sur le ListBox, donc je suppose que vous l'avez omis. Si vous vous liez à quelque chose comme un ObservableCollection <> alors chaque élément dans le ListBox aura sa propre classe ViewModel. Vous pouvez avoir des méthodes publiques sur ceux que vous aimez.

Si vous souhaitez gérer un événement dans le contrôle personnalisé, gérez-le dans le code le plus bas possible, dans ce cas dans le code-behind de UserControl. Puis, dans chaque ViewModel, vous avez une instance ICommand (ou une commande routée si cela vous convient). Dans UserControl, vous disposez d'un DataContext que vous pouvez convertir en type de votre ViewModel. Ainsi, le gestionnaire d'événements peut accéder à ViewModel et exécuter des commandes.

Voici Josh Smith's article on Routed Commands que vous pourriez trouver intéressant

Dans cet article sur Apps with MVVM architecture, Josh décrit ICommands personnalisés

(Ceci est pseudo-code)

class ViewModelType { 
    public void DoSomething() { /* ... */ } 
    public ICommand DoSomethingCommand { get; set; } 
    public string Property { get; set; } 
} 

class CodeBehind { 
    public void EventHandler(object, args) { 
     (DataContext as ViewModelType).DoSomethingElseCommand.Execute(); 
    } 
}