Привязать Silverlight TabControl к коллекции - PullRequest
5 голосов
/ 02 сентября 2010

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

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

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

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

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

Рекомендуемый преобразователь :

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

1 Ответ

2 голосов
/ 03 июня 2011

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

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>

И преобразовать привязку, шаблон управления

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

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

...