WPF数据模板绑定

4
我发现当在WPF TabControl中使用ContentTemplate/DataTemplate时,我的绑定将不再起作用。
我设置了一个小例子来说明:
<Window x:Class="HAND.BindingExample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="BindingExample" Height="506" Width="656"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    >
<Grid>
    <TabControl HorizontalAlignment="Left" Height="381"  VerticalAlignment="Top" Width="608">
        <TabItem Header="TabItem">
            <Label Content="{Binding Path=myString}"/>
        </TabItem>
        <TabItem Header="TabItem">
            <TabItem.ContentTemplate>
                <DataTemplate>
                    <Label Content="{Binding Path=myString}"/>
                </DataTemplate>
            </TabItem.ContentTemplate>
        </TabItem>
    </TabControl>
</Grid>
</Window>

Tab1正常工作,Tab2为空。

背后的代码:

using System.Windows;

namespace HAND
{
    public partial class BindingExample : Window
    {
        public string myString { get; set; }

        public BindingExample()
        {
            myString = "Hello Stackoverflow";

            InitializeComponent();
        }
    }
}
2个回答

6
您正在不正确地使用ContentTemplate属性。根据MSDN上ContentControl.ContentTemplate属性页面的说明:

获取或设置用于显示ContentControl内容的数据模板。

因此,在设置此属性时,您还需要将Content属性设置为某种数据源:
<TabControl>
    <TabItem Header="TabItem">
        <Label Content="{Binding Path=myString}"/>
    </TabItem>
    <TabItem Header="TabItem" Content="{Binding Path=myString}">
        <TabItem.ContentTemplate>
            <DataTemplate>
                <Label Content="{Binding}" />
            </DataTemplate>
        </TabItem.ContentTemplate>
    </TabItem>
</TabControl>

和Miiite得出了相同的结论。非常感谢你的好解释! - ejones
为什么需要在<TabItem>中设置Content="{Binding Path=mystring}",然后在<Label>中也设置Content="{Binding}"?在这个例子中,似乎根本不需要TabItem.ContentTemplate?没有模板也能正常工作吗?我正在尝试理解模板以及如何将标签的其他属性绑定到父级的DataContext...谢谢! - stuzor
我们将 myString 属性数据绑定到 Content 属性,以给它一些值。在这里,该值只是一个单独的字符串,但它也可以是带有其他属性的对象。在 ContentTemplate 中,我们告诉它我们想要在 Label 中显示数据绑定对象的哪个部分。在这种情况下,我们想要绑定整个字符串对象,所以我们使用 {Binding} 来实现。 - Sheridan
请注意:此示例仅适用于只读绑定 - 如果您将“Label”更改为“TextBox”,则myString永远不会被写回。 - wondra

4
<TabItem Content="{Binding myString}" Header="TabItem">
    <TabItem.ContentTemplate>
        <DataTemplate>
            <Label Content="{Binding}" />
        </DataTemplate>
    </TabItem.ContentTemplate>
</TabItem>

但是要注意的是,将窗口绑定在自身上并不是正确的方法。我不知道你是否只是为了举个例子而这样做的,但如果不是,请尝试创建一个正确的viewModel来绑定你的窗口。


我已经在我的计算机上运行它了。也许当您将一个窗口绑定在自身上时,它无法运行,而我没有这样做。 - Miiite
谢谢!这对我的例子有效。在我的真实世界的程序中,我使用了不同的绑定类来使用MVVM模式。我仍然不明白为什么你的代码可以工作而我的不能。我现在将尝试将这个例子的解决方案应用到我的应用程序中。 - ejones
Sheridan发布了一个与我相同的XAML代码答案,但更好地解释了ContentTemplate的工作原理。这应该有助于您理解它。 - Miiite
是的,谢谢你们两个! - ejones
嗨,miiite,你的答案对我有用,只是测试错误了。请编辑你的答案,我会撤销那个踩的。 - Sivasubramanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接