TabControl: SelectedContent и SelectedItem возвращают одинаковые - PullRequest
2 голосов
/ 01 февраля 2012

Я отображаю список пользовательских объектов (здесь: Customer) динамически, каждый на своей вкладке, используя TabControl, ItemsSource и DataTemplate:

MainWindows.xaml.cs:

using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace testTabControl
{
    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int NumberOfContracts { get; set; }
    } 

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            //create all
            var customers = new List<Customer>
            {
                new Customer {FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23},
                new Customer {FirstName = "Jane", LastName = "Smiths", NumberOfContracts = 42},
                new Customer {FirstName = "John", LastName = "Tester", NumberOfContracts = 32}
            };

            //show
            myTabControl.ItemsSource = customers;

        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            Trace.WriteLine("myTabControl.SelectedContent is " + myTabControl.SelectedContent.GetType());
            Trace.WriteLine("myTabControl.SelectedItem    is " + myTabControl.SelectedItem.GetType());

            // do something with content of the selected tab:
            ///myTabControl.SelectedContent.Foreground = new SolidColorBrush(Color.FromRgb(255, 0, 0));
        }
    }    
}

MainWindow.xaml:

    <Window x:Class="testTabControl.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:testTabControl="clr-namespace:testTabControl" 
            Title="MainWindow" Height="350" Width="525"
            SizeChanged="OnSizeChanged"
            >
        <Window.Resources>

            <DataTemplate x:Key="myContent" DataType="{x:Type testTabControl:Customer}">
                <TextBlock x:Name="myContentRoot">
                    This is the content for 
                    <TextBlock Text="{Binding FirstName}"/> <TextBlock Text="{Binding LastName}"/>
                </TextBlock>
            </DataTemplate>

            <DataTemplate x:Key="myHeader" DataType="{x:Type testTabControl:Customer}">
                <TextBlock Text="{Binding LastName}"/>
            </DataTemplate>

        </Window.Resources>

        <TabControl 
            x:Name="myTabControl" 
            SelectedIndex="0" 
            ItemTemplate="{StaticResource ResourceKey=myHeader}"
            ContentTemplate="{StaticResource ResourceKey=myContent}"
         />

    </Window>

В методе OnSizeChanged я ожидал, что myTabControl.SelectedContent вернет TextBlock, созданный из DataTemplate.Но экземпляр клиента возвращается!То же, что myTabControl.SelectedItem.

Единственный способ найти сгенерированный контент, который я нашел, описан здесь: http://msdn.microsoft.com/en-us/library/bb613579.aspx

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

Ответы [ 2 ]

2 голосов
/ 01 февраля 2012

Ваш TabControl содержит объекты типа Customer.Templates может использоваться для указания WPF, как рисовать каждый Customer объект, однако это не меняет того факта, что элементы в TabControl по-прежнему Customer объектов.

Если вы хотитечтобы получить доступ к шаблонному объекту пользовательского интерфейса для элемента, вы можете пройтись по VisualTree или использовать ItemContainerGenerator, чтобы получить контейнер, содержащий SelectedItem

Например,

var selectedItem = myTabControl.SelectedItem;

var selectedItemContainer = 
    myTabControl.ItemContainerGenerator.ContainerFromItem(selectedItem);
1 голос
/ 01 февраля 2012

Причина, по которой SelectedContent возвращает объект Customer, заключается в следующем:

<DataTemplate x:Key="myContent" DataType="{x:Type testTabControl:Customer}">

Он возвращает именно то, о чем вы просили.Все, что делает DataTemplate, это описывает, как отобразить объект Customer, который является содержимым, и ничего больше.Когда вы запрашиваете контент, он возвращает объект, который отображает шаблон данных.

Один из способов сделать это свойство для вашего объекта Customer, которое реплицирует желаемый результат.

public string OutputString
{
    get
    {
        return string.Format("This is the content for {0} {1}", this.FirstName, this.LastName);
    }

}

А затем сделать что-то вроде

Trace.WriteLine("myTabControl.SelectedContent is " + myTabControl.SelectedContent.OutputString);

Или вы можете создать коллекцию строк, которая соответствует приведенному выше формату, и сделать их содержимым.Тогда ваш SelectedContent будет простой строкой по умолчанию.

...