2009-12-29 4 views
2

J'écris une application avec WPF et une partie de celle-ci implique de gérer pour l'utilisateur divers fichiers qui sont utilisés pour configurer des périphériques internes personnalisés. Je dois être capable de manipuler différents types de configurations dans des onglets dans le même TabControl, ce qui signifie que le contenu des TabItems doit être généré dynamiquement. Je voudrais le faire avec ControlTemplates, mais je n'ai pas encore réussi à obtenir un modèle de travail. J'ai un ControlTemplate appelé « pendantConfigurationTabItemTemplate » défini dans mes ressources de la fenêtre, et j'utilise le code suivant pour appliquer le modèle (qui contient un élément nommé je besoin d'accéder) aux TabItems et les ajouter à leur TabControl mère:Créer des TabItems avec un contenu différent à l'exécution basé sur des modèles dans WPF

<ControlTemplate x:Key="pendantConfigurationTabItemTemplate" TargetType="TabItem"> 
    <StackPanel Orientation="Vertical"> 
     <my:PendantConfigurationFileEditor x:Name="configurationEditor"/> 
     <StackPanel Style="{StaticResource defaultOkCancelButtonsContainerStyle}"> 
      <Button Style="{StaticResource defaultOkCancelButtonStyle}"/> 
      <Button Style="{StaticResource defaultOkCancelButtonStyle}" Click="OkButton_Click"/> 
     </StackPanel> 
    </StackPanel> 
</ControlTemplate> 

code derrière:

TabItem ConfigTab = new TabItem(); 

switch (ConfigFile.Device) 
{ 
    case DeviceType.PENDANT: 
{ 
    ControlTemplate TabTemplate = Resources["pendantConfigurationTabItemTemplate"] as ControlTemplate; 

    ConfigTab.Template = TabTemplate; 
    ConfigTab.ApplyTemplate(); 

    object Editor = TabTemplate.FindName("configurationEditor", ConfigTab); 

    PendantConfigurationFileEditor ConfigFileEditor = Editor as PendantConfigurationFileEditor; 

    ConfigFileEditor.PendantConfiguration = DeviceConfig; 

    break; 
} 
default: 
    /* snipped */ 
    return; 
} 

ConfigTab.Header = ConfigFile.ConfigurationName; 

this.EditorTabs.Items.Add(ConfigTab); 
this.EditorTabs.SelectedIndex = this.EditorTabs.Items.Count - 1; 

Cependant, chaque fois que je lance le programme, sans onglets sont ajoutés au contrôle onglet, au lieu du contrôle onglet (apparemment) sera remplacé ou couvert par le contenu du modèle. Est-ce que quelqu'un peut m'aider avec ça?

En effet, ce que je veux faire est d'utiliser les modèles WPF comme les usines TabItem

Répondre

5

TabControl.ItemsSource DataTemplates plus est effectivement la solution « modèles comme usines » vous demandez, mais il exige une approche légèrement différente de votre position actuelle un. Plutôt que d'écrire du code procédural pour créer et modéliser des TabItems et appeler Items.Add, utilisez la propriété ItemsSource et la liaison de données. Cela provoquera WPF pour créer un TabItem pour chaque objet dans ItemsSource. Vous pouvez ensuite utiliser ContentTemplateSelector pour sélectionner les modèles appropriés pour l'objet affiché sur cet onglet, en fonction des critères appropriés (par exemple, la propriété Device). Toutefois, dans ce cas, vous utiliserez DataTemplates plutôt que ControlTemplates.

Votre sélection ressemblera à quelque chose comme ceci:

public class DeviceTypeSelector : DataTemplateSelector 
{ 
    public DataTemplate PendantTemplate { get; set; } 
    public DataTemplate DefaultTemplate { get; set; } 

    public override SelectTemplate(object item, DependencyObject container) 
    { 
    ConfigFile cf = (ConfigFile)item; 
    switch (cf.Device) 
    { 
     case DeviceType.Pendant: return PendantTemplate; 
     default: return DefaultTemplate; 
    } 
    } 
} 

et sera instancié en XAML comme ceci:

<local:DeviceTypeSelector x:Key="dts" 
          PendantTemplate="{StaticResource pt}" 
          DefaultTemplate="{StaticResource dt}" /> 

(où pt et dt sont DataTemplates appropriés définis ailleurs dans les ressources).

Enfin, votre TabControl ressemblera à ceci:

<TabControl Name="EditorTabs" 
      ContentTemplateSelector="{StaticResource dts}" /> 

et vous configurer comme EditorTabs.ItemsSource = myConfigFiles; (ou mieux laisser encore acquérir la ItemsSource en XAML du DataContext).

Vous devrez également configurer les en-têtes des TabItems: pour ce faire, utilisez TabControl.ItemContainerStyle, avec une propriété Setter pour l'en-tête. Je pense que cela ressemblerait à quelque chose comme ceci:

<TabControl ...> 
    <TabControl.ItemContainerStyle> 
    <Style TargetType="TabItem"> 
     <Setter Property="Header" Value="{Binding ConfigurationName}" /> 
    </Style> 
    </TabControl.ItemContainerStyle> 
</TabControl> 

(Vous pouvez également inline le ContentTemplateSelector, par la manière. Je me suis cassé dehors dans une ressource la plupart du temps de façon à montrer les choses en petits morceaux)

+0

C'est une bonne réponse, je vais essayer. Cependant, je pensais que DataTemplates étaient plus destinés à afficher des données et ControlTemplates étaient destinés à être utilisés comme des contrôles réutilisables afin de réduire le nombre de UserControls qui doivent être créés?Je dois être en mesure d'éditer les objets qui sont affichés/databound dans les onglets –

+0

N'ayez pas peur, les DataTemplates sont destinés à afficher * et éditer * des données. Ils peuvent absolument contenir des éléments d'interface utilisateur qui mettent à jour l'objet affiché. Assurez-vous simplement que la liaison d'élément dans le DataTemplate est bidirectionnelle (c'est la valeur par défaut pour les zones de texte, mais pas pour tous les contrôles). ControlTemplates sont plus sur la modification de l'interface utilisateur des contrôles tout en tirant parti de leur comportement existant, par exemple. faire un bouton apparaître comme un graphique autonome sans le bouton chrome habituel, ou un TabControl comme un carrousel, Rolodex ou un cahier (papier). – itowlson

+0

Votre suggestion a fonctionné, et plutôt bien. Merci beaucoup, j'apprécie vraiment :) –

Questions connexes