How bind TabControl?

烈酒焚心 提交于 2019-12-22 21:21:49

问题


xaml

<controls:TabControl x:Name="tabControlRoom" Grid.Row="1" Grid.Column="1" d:LayoutOverrides="Width, Height" ItemsSource="{Binding}" >
            <controls:TabControl.ItemTemplate>
                <DataTemplate>
                    <controls:TabItem Header="{Binding name}">
                        <StackPanel Margin="10" Orientation="Horizontal">

                        </StackPanel>
                    </controls:TabItem>
                </DataTemplate>
            </controls:TabControl.ItemTemplate>
        </controls:TabControl>

and code

m_roomContext.Load(m_roomContext.GetRoomQuery());
                tabControlRoom.DataContext = m_roomContext.Rooms;

when I open this page, then there is all the elements, but a second later I see only a white screen

error:

load operation failed for query 'GetRoom'. Unable to cast object of type 'Web.Room' to type 'System.Windows.Controls.TabItem'/'


回答1:


Create converter

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

Create ControlTemplate:

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

And binding convert, controltemplate

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

taken from the blog binding-tabcontrol




回答2:


When binding the TabControl there are two things you need to accomplish, one is the header content for the TabItem the other is the content for the selected TabItem, which is generally another user control.

The way have I've solved this in the past is to bind ItemsSource of the TabControl to a collection of view models, and to provide two data templates, one to supply the header content for the TabItem, an the other to supply the content for the selected TabItem, which maps to a view.

<Window.Resources>
    <DataTemplate x:Key="ItemTemplate">
        <TextBlock Text="{Binding Title}" />
    </DataTemplate>

    <DataTemplate x:Key="ContentTemplate">
        <local:SampleView />
    </DataTemplate>
</Window.Resources>

<Grid>
    <TabControl 
        ItemsSource="{Binding SampleViewModels}" 
        ItemTemplate="{StaticResource ItemTemplate}"
        ContentTemplate="{StaticResource ContentTemplate}"
        SelectedIndex="0"
        />
</Grid>


来源:https://stackoverflow.com/questions/6174002/how-bind-tabcontrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!