2012-04-16 2 views
1

Je suis très nouveau pour WPF et je écris une application utilisant cet exemple comme point de départ http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090025Comment changer de se lier ObervableCollection à un TabControl à un ContentControl

Je n'avoir un espace de travail visible à tout temps, donc je veux me débarrasser du TabControl et utiliser quelque chose de simple à la place - probablement un ContentControl, je ne suis vraiment pas sûr mais tout ce qu'il doit faire est d'avoir du contenu et être fermable. Donc, je suis en train de remplacer:

<DataTemplate x:Key="WorkspacesTemplate"><TabControl 
    IsSynchronizedWithCurrentItem="True" 
    ItemsSource="{Binding}" 
    ItemTemplate="{StaticResource ClosableTabItemTemplate}" 
    Margin="4" 
    /> 

avec:

<DataTemplate x:Key="WorkspacesTemplate"> 
    <ContentControl Content="{Binding ??}" ContentTemplate="{StaticResource ClosableTabItemTemplate}"/> 
</DataTemplate> 

mais je ne sais pas quoi lier. Le code dans l'exemple semble utiliser CollectionViewSource pour définir l'espace de travail actif - c'est l'espace de travail actif qui m'intéresse mais je ne comprends pas ce que TabControl fait, sauf que c'est quelque chose à voir avec IsSynchronizedWithCurrentItem = "Vrai"

le modèle est invoqué à partir d'ici (Workspaces est le ObservableCollection de ViewModels):

<HeaderedContentControl Content="{Binding Path=Workspaces}" ContentTemplate="{StaticResource WorkspacesTemplate}" Header="Workspaces" Style="{StaticResource MainHCCStyle}"/> 

et voici le modèle ClosableItem:

<DataTemplate x:Key="ClosableTabItemTemplate"> 
    <DockPanel Width="120"> 
     <Button 
    Command="{Binding Path=CloseCommand}" 
    Content="X" 
    Cursor="Hand" 
    DockPanel.Dock="Right" 
    Focusable="False" 
    FontFamily="Courier" 
    FontSize="9" 
    FontWeight="Bold" 
    Margin="0,1,0,0" 
    Padding="0" 
    VerticalContentAlignment="Bottom" 
    Width="16" Height="16" 
    /> 
     <ContentPresenter 
    Content="{Binding Path=DisplayName}" 
    VerticalAlignment="Center" 
    /> 
    </DockPanel> 
</DataTemplate> 

S'il vous plaît quelqu'un peut-il expliquer ce que je dois faire? Merci

Répondre

2

Le WorkspacesTemplate indique à WPF comment afficher la propriété Workspaces, qui, comme vous le dites, est un ObservableCollection de ViewModels. Donc, le WorkspacesTemplate dit, afficher tous ces ViewModels dans un onglet de contrôle, et pour chaque ViewModel, utilisez le ClosableTabItemTemplate pour afficher le ViewModel dans un onglet.

Puisque vous ne voulez qu'un seul espace de travail visible à la fois, vous n'avez pas besoin d'exposer une collection d'espaces de travail à partir de votre ViewModel, et vous n'avez pas besoin d'un onglet pour les afficher. Vous exposer simplement l'espace de travail actuel de votre ViewModel et fournir un peu de XAML pour l'afficher.

Si vous voulez continuer à utiliser un modèle pour envelopper le ViewModel, alors oui, vous pouvez simplement utiliser un ContentControl pour invoquer le modèle:

<DataTemplate x:Key="MySingleWorkspaceTemplate"> 
    <TextBlock Text={Binding Blah} /> 
    <!-- etc --> 
</DataTemplate> 

et d'invoquer le modèle

<ContentControl Content="{Binding CurrentWorkspace}" ContentTemplate="{StaticResource MySingleWorkspaceTemplate}"/> 

Cependant, si c'est le seul endroit où le XAML va être utilisé, vous pouvez aussi bien oublier le modèle et déclarer le XAML directement. Par exemple, (au lieu de ContentControl)

<TextBlock Text={Binding CurrentWorkspace.Blah} /> 
<!-- etc --> 

RÉVISÉ À AJOUTER:

Je pense que vous pourriez obtenir confus parce qu'actuellement, le ViewModel n'a pas de concept du « espace de travail sélectionné », il expose simplement une collection . Pour être complet (mais ne vous inquiétez pas pour tout cela), la sélection est introduite par le TabControl qui utilise indirectement la valeur par défaut CollectionView pour la collection Workspaces, et CollectionView a le concept d'un élément sélectionné. Tout est dans la vue.

Je ne m'inquiéterais pas de tout cela maintenant, exposer vous-même l'espace de travail de votre ViewModel.

EDIT2:

bouton de fermeture apparaît parce que vous définissez explicitement une ContentTemplate sur votre HeaderedContentControl. Ce modèle apparaîtra indépendamment de Content.

Pour qu'un modèle apparaisse uniquement lorsqu'il y a des données dans Content, définissez le modèle implicite à la place. Si vous ajoutez un DataType à votre définition de modèle (et supprimez la clé), vous dites à WPF d'utiliser toujours ce modèle pour afficher un objet de ce type de données.

<DataTemplate DataType="{x:Type vm:WorkspaceViewModel}"> 
    <!-- Blah --> 
</DataTemplate> 

Ensuite, vous pouvez supprimer le modèle explicite de votre HeaderedContentControl. Définir simplement le Content suffira pour invoquer le modèle, et s'il n'y a pas de contenu, il n'y a pas de modèle.

<HeaderedContentControl Content="{Binding Path=CurrentWorkspace}" /> 

(ps. Si vous ne l'utilisez l'en-tête de HeaderedContentControl, vous pourriez tout aussi bien utiliser une norme de tourbière ContentControl)

+0

Oui, le bit je comprends ne surtout pas comment était TabControl interagissait avec la CollectionViewSource. De toute façon, je me bats encore. J'ai exposé CurrentWorkspace et je fais Nix

+0

et quel est le problème? – GazTheDestroyer

+0

Une partie du problème est que je ne sais même pas quel contrôle utiliser. Les ViewModels que je charge sont des composites avec beaucoup de contrôles usuels, donc je veux juste un panneau fermable mais je ne sais pas s'il y a un type de panneau ou quoi. Je ne veux pas de fenêtre, c'est pourquoi j'ai essayé de garder le modèle ClosableItem. – Nix

Questions connexes