如何将 TabItem Header 绑定到 FrameworkElementFactory 中的 TextBox?

How to bind a TabItem Header to a TextBox in FrameworkElementFactory?

我试图创建一个 TabItem,里面有 TextBox 来自 this article

我发现 TabItem Header 未绑定到 TextBox

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    TabItem ti = new TabItem();
    DataTemplate tabItemTemplate = new DataTemplate();

    tabItemTemplate.DataType = typeof(TabItem);
    FrameworkElementFactory textBoxFactory = new FrameworkElementFactory(typeof(TextBox));
    textBoxFactory.SetBinding(TextBox.TextProperty, new Binding("."));
    textBoxFactory.SetValue(NameProperty, "textBox");
    textBoxFactory.SetValue(BorderThicknessProperty, new Thickness(0));
    //textBoxFactory.SetValue(IsEnabledProperty, false);
    tabItemTemplate.VisualTree = textBoxFactory;
    ti.Header = "Test!";
    ti.HeaderTemplate = tabItemTemplate;
    ti.MouseDoubleClick += TabItem_MouseDoubleClick;
    tabControl.Items.Add(ti);
}

private void TabItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show((sender as TabItem).Header.ToString());
}

谁能教教我如何正确绑定吗?

非常感谢!

您的 Binding 配置有误。

new Binding(".") 缺少 Binding.Source.
应该是:

var binding = new Binding("Header") { Source = ti };

使用示例XAML

以下示例复制您的 C# 代码

<TabControl>
  <TabItem Header="Test" MouseDoubleClick="TabItem_MouseDoubleClick" >
    <TabItem.HeaderTemplate>
      <DataTemplate>
        <TextBox x:Name="textBox" 
                 Text="{Binding RelativeSource={RelativeSource AncestorType=TabItem}, Path=Header}" />
       </DataTemplate>
     </TabItem.HeaderTemplate>
   </TabItem>
 </TabControl>

补充@BionicCode的回答

您的原始绑定存在问题,因为您指向的是当前数据上下文。
你的绑定相当于一个空的绑定"new Binding();".
因此,您获得的绑定不是绑定到 属性,而是绑定到源(默认源是当前数据上下文)。
但是绑定只能改变源的属性,不能改变源本身。
Header 模板应用于 TabItem 的 Header 属性.
的内容 因此,要获得相同的值,但不是作为绑定的源,而是作为绑定的 Path 中的 属性,您需要上到 TabItem 级别。
@BionicCode 在他的回答中向您展示了此类绑定的示例。

我将提供另一个选项以集成到您的代码中:

        private static readonly DataTemplate headerTemplate = (DataTemplate)XamlReader.Parse
            (@"
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
              xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
    <TextBox x:Name='textBox'
             Text='{Binding Header,
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}},
                            UpdateSourceTrigger=PropertyChanged}'
             BorderThickness='0'/>
</DataTemplate>
            ");

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            TabItem ti = new TabItem();
            ti.Header = "Test!";
            ti.HeaderTemplate = headerTemplate;
            ti.MouseDoubleClick += TabItem_MouseDoubleClick;
            tabControl.Items.Add(ti);
        }