我正在动态显示自定义对象列表(此处为: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
有没有人知道没有视觉树步行的任何其他解决方案吗?
答案 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将是一个简单的字符串。