2010-09-02 3 views
5

У меня есть коллекция Model-объектов в моей модели ViewModel. Я хотел бы иметь возможность привязать TabControl к ним и использовать DataTemplate для извлечения информации из объектов Model. Когда я пытаюсь это сделать, я получаю errormessage: Невозможно передать объект типа Model объекту типа TabItem. Пробыв некоторое время в поисках решения я нашел следующее:Привязать Silverlight TabControl к коллекции

  1. The Silverlight TabControl является сломана. Используйте комбинацию ListBox и ContentControl для имитации поведения TabControl . (Значит , что у меня есть к коже в ListBox, чтобы выглядеть как TabControl)

  2. TabControl не отменяет PrepareContainerForItemOverride и решение является сделать Converter. (Не так хорошо, потому что я затем нужно указать тип convertee в конвертер)

Кто-нибудь знает какие-либо лучшее решение?

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

Я создал расширенный вкладок, который не нужен преобразователь и работает правильно с классом ObservableCollection. http://vortexwolf.wordpress.com/2011/04/09/silverlight-tabcontrol-with-data-binding/ – vorrtex

ответ

2

Создать конвертер

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"); 
     } 

Создание ControlTemplate:

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

И связывание новообращенный, ControlTemplate

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

взяты из блога binding-tabcontrol

+1

Пожалуйста, подведите итог содержания своего блога на английском языке. Кроме того, вам необходимо сообщить, что это ваша собственная работа, когда вы ссылаетесь на свой блог или на любой сайт, продукт или проект, с которыми вы связаны. См. [Могу ли я продвигать продукты или сайты, с которыми я связан здесь?] (Http://stackoverflow.com/faq#promotion) в разделе FAQ. –

Смежные вопросы