我的ViewModel中有一个模型对象集合.我希望能够将TabControl绑定到这些并使用DataTemplate从Model对象中提取信息.当我尝试这样做时,我得到errormessage:无法将Model类型的对象强制转换为TabItem类型的对象.花了一些时间寻找解决方案后,我发现了以下内容:
> Silverlight TabControl是
破碎.使用ListBox的组合
和ContentControl来模仿
TabControl的行为. (手段
我必须将ListBox设置为皮肤
看起来像TabControl)
> TabControl不会覆盖
PrepareContainerForItemOverride和
解决方案是制作一个
转换器. (因为我不太好
然后需要指定的类型
转换器中的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"} }; }
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,System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
解决方法
创建转换器
public class SourceToTabItemsConverter : IValueConverter { public object Convert(object value,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,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>