TabControl:SelectedContent和SelectedItem返回相同

时间:2012-02-01 15:09:21

标签: wpf tabcontrol

我正在动态显示自定义对象列表(此处为: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返回从DataTemplate生成的TextBlock。但是返回了一个客户实例!与myTabControl.SelectedItem相同。

我在此处描述了获取生成内容的唯一方法:http://msdn.microsoft.com/en-us/library/bb613579.aspx

有没有人知道没有视觉树步行的任何其他解决方案吗?

2 个答案:

答案 0 :(得分:2)

您的TabControl包含Customer类型的对象。 Templates可用于告诉WPF如何绘制每个Customer对象,但它不会改变TabControl中的项仍为Customer个对象的事实。 / p>

如果您想要访问该项目的模板化UI对象,您可以走VisualTree或使用ItemContainerGenerator获取容纳SelectedItem的容器

例如,

var selectedItem = myTabControl.SelectedItem;

var selectedItemContainer = 
    myTabControl.ItemContainerGenerator.ContainerFromItem(selectedItem);

答案 1 :(得分:1)

您的SelectedContent返回Customer对象的原因是:

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

它正在回归你所要求的。所有DataTemplate都描述了如何显示 内容的Customer对象,没有别的。当您要求内容时,它返回DataTemplate正在显示的对象。

你可以做的一种方法是在你的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将是一个简单的字符串。