2010-09-02 15 views
5

J'ai une collection d'objets-modèles dans mon ViewModel. Je voudrais pouvoir lier un TabControl à ceux-ci et utiliser un DataTemplate pour extraire les informations des objets Model. Quand j'essaye de faire ceci je reçois le message d'erreur: Impossible de convertir l'objet de type Model en objet de type TabItem. Après avoir passé quelque temps à la recherche d'une solution que je trouve les suivantes:Lier un SilverControl TabControl à une collection

  1. Le Silverlight TabControl est cassé. Utilisez une combinaison de ListBox et ContentControl pour imiter le comportement d'un TabControl. (Moyens que je dois à la peau ListBox à ressembler à un TabControl)

  2. TabControl ne remplace pas PrepareContainerForItemOverride et la solution est de faire un Converter. (Pas si bon parce que je alors besoin de spécifier le type de convertee dans le convertisseur)

Quelqu'un sait une meilleure solution?

XAML

<sdk:TabControl ItemsSource="{Binding Items, ElementName=MyControl}"> 
     <sdk:TabControl.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Name}" /> 
      </DataTemplate> 
     </sdk:TabControl.ItemTemplate> 
    </sdk:TabControl> 

C#

public ObservableCollection<Model> Items { get; set; } 

public ViewModel() 

    Items = new ObservableCollection<Model>{ 
     new Model { Name = "1"}, 
     new Model { Name = "2"}, 
     new Model { Name = "3"}, 
     new Model { Name = "4"} 
    }; 
} 

Suggested Converter:

public class TabConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     List<TabSource> source = value as List<TabSource>; 
     if (source != null) 
     { 
      List<TabItem> result = new List<TabItem>(); 
      foreach (TabSource tab in source) 
      { 
       result.Add(new TabItem() 
       { 
        Header = tab.Header, 
        Content = tab.Content 
       }); 
      } 
      return result; 
     } 
     return null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

J'ai créé le contrôle onglet étendu qui n'a pas besoin d'un convertisseur et fonctionne correctement avec la classe ObservableCollection. http://vortexwolf.wordpress.com/2011/04/09/silverlight-tabcontrol-with-data-binding/ – vorrtex

Répondre

2

Créer convertisseur

public class SourceToTabItemsConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      try 
      { 
       var source = (IEnumerable)value; 
       if (source != null) 
       { 
        var controlTemplate = (ControlTemplate)parameter; 

        var tabItems = new List<TabItem>(); 

        foreach (object item in source) 
        { 
         PropertyInfo[] propertyInfos = item.GetType().GetProperties(); 

         //тут мы выбираем, то поле которое будет Header. Вы должны сами вводить это значение. 
         var propertyInfo = propertyInfos.First(x => x.Name == "name"); 

         string headerText = null; 
         if (propertyInfo != null) 
         { 
          object propValue = propertyInfo.GetValue(item, null); 
          headerText = (propValue ?? string.Empty).ToString(); 
         } 

         var tabItem = new TabItem 
              { 
               DataContext = item, 
               Header = headerText, 
               Content = 
                controlTemplate == null 
                 ? item 
                 : new ContentControl { Template = controlTemplate } 
              }; 

         tabItems.Add(tabItem); 
        } 

        return tabItems; 
       } 
       return null; 
      } 
      catch (Exception) 
      { 
       return null; 
      } 
     } 

     /// <summary> 
     /// ConvertBack method is not supported 
     /// </summary> 
     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotSupportedException("ConvertBack method is not supported"); 
     } 

Créer ControlTemplate:

<ControlTemplate x:Key="MyTabItemContentTemplate"> 
      <StackPanel> 
       <TextBlock Text="{Binding Path=name}" /> 
      </StackPanel> 
     </ControlTemplate> 

et convertir la liaison, ControlTemplate

<controls:TabControl x:Name="tabControl" 
     ItemsSource="{Binding ElementName=tabControl, 
           Path=DataContext, 
           Converter={StaticResource ConverterCollectionToTabItems}, 
           ConverterParameter={StaticResource MyTabItemContentTemplate}}"> 
     </controls:TabControl> 

pris du blog binding-tabcontrol

+1

Veuillez résumer le contenu de votre article ici en anglais. En outre, vous devez indiquer que c'est votre propre travail lorsque vous créez un lien vers votre blog ou un site Web, un produit ou un projet auquel vous êtes affilié. Voir la section [Puis-je promouvoir des produits ou des sites Web auxquels je suis affilié ici?] (Http://stackoverflow.com/faq#promotion) de la section FAQ. –