鉴于以下XAML:
<TabControl DataContext="{StaticResource mainVM}" ItemsSource="{Binding MovableVM.Docked, UpdateSourceTrigger=PropertyChanged}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock Text="{Binding ContentTitle}"/>
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
我希望两个DataTemplate
具有相同的DataContext
,其预期结果是ItemsSource中的实际项目(实现IMovable接口的UserControl
,见下文)显示在单独的选项卡和每个选项卡的标题,以显示同一项目的属性ContentTitle的内容。
IMovable
对象 按预期显示,但与ContentTitle的绑定不正在为标头工作。如果我更改ContentTemplate
中的绑定,就像这样......
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding ContentTitle}"/>
</DataTemplate>
</TabControl.ContentTemplate>
...我确实获取了ContentTitle属性的内容而不是item,因此属性本身是可绑定的。
这是IMovable
界面:
public interface IMovable : INotifyPropertyChanged
{
string ContentTitle { get; }
}
所以我的问题是:ItemTemplate中是否有不同的DataContext(如果是这样,它是什么?)或者是否有其他原因导致ItemTemplate中的绑定无法正常工作?
<击>的更新 我已经创建了一个小例子应用程序,可以清楚地显示问题。如果事情按预期工作,则每个选项卡中的每个Ellipse下面都会有一个文本,而Ellipse的DataContext将不为null。它可以在这里下载:Example App
更新
如果使用自定义类Foo::DependencyObject
并将ContentTitle属性设置为DependencyProperty,则它可以正常工作。虽然更改原始类中的属性不起作用。我需要睡在这...... [/ p>
更新 我已经缩小了问题范围,但调查结果与我的预期完全不同。 WpfApplication2表明向ItemsSource添加POCO或从DependedcyObject派生的项目按预期工作。但是,从UserControl派生的项目不会给出预期的结果。如果有人看看你,我将不胜感激。只需运行该应用程序,您就会看到一个Tab标题缺少文本。
答案 0 :(得分:3)
重写ItemContainerStyle而不是ItemTemplate为我工作:
<TabControl
SelectedIndex="{Binding ElementName=this, Path=SelectedIndex}"
ItemsSource="{Binding ElementName=this, Path=Items}"
TabStripPlacement="Left"
Visibility="{Binding ElementName=this, Path=ShowTabs, Converter={StaticResource _trueToVisibleConverter}}">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Path=Title}" />
</Style>
</TabControl.ItemContainerStyle>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
根据以下MSDN帖子,问题是我试图将我绑定到的UIElement添加到可视树中的两个不同位置(内容区域和标题区域)。请参阅帖子以获得更好的解释。
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/0a4622ac-5990-4b6e-bf38-0acb10cd68c7/
答案 1 :(得分:0)
我也需要vm代码以确保,但看起来上下文位于主vm内,而不是表示每个标签项的子vm,内容模板上下文是主vm和项模板上下文tab vm。
答案 2 :(得分:0)
是的,他们是一样的。因此,如果绑定到{Binding}
中的ContentTemplate
,则会绑定到对象本身。
在您的情况下:ItemTemplate
有一个IMovable
对象作为数据上下文,实际上ContentTemplate
具有相同的数据上下文:IMovable
对象。
您可能认为ItemTemplate
选择其他数据上下文。事实并非如此。
答案 3 :(得分:0)
这里的问题是DataTemplate会看到一个继承自Visual的对象。这种类型的对象不需要通过DataTemplate进行任何可视化表示。这篇文章对此进行了讨论。
DataTemplate DataType property doesn't work on types inherited from Control