0

我正在使用其 ItemSource 属性将集合绑定到 TabControl。

我在代码中而不是在 XAML 中编写 WPF 以获得更深入的理解。

我面临的问题是,如果我想将 TabItem 的标题绑定到属性(“EntityID”),则绑定不会启动。

如果我设置一个值而不是绑定,则该代码有效(注释中的代码如下)

var binding = new Binding();
binding.Path = new PropertyPath("EntityID");

DataTemplate itemTemplate = new DataTemplate();
var label = new FrameworkElementFactory(typeof(Label));

//label.SetValue(Label.ContentProperty,"test");
label.SetBinding(Label.ContentProperty, binding);

itemTemplate.VisualTree = label;

_tabControl.ItemTemplate = itemTemplate;

此外,如果设置 ContentTemplate 而不是 ItemTemplate,则绑定也可以正常工作。

如何从纯代码将选项卡标题绑定到我的 ItemsSource 的属性?

4

2 回答 2

1

有很多方法可以从 Code Behind 设置绑定。您应该尝试绑定的是 TabItem 上的 HeaderProperty。尽管您必须先检索它才能做到这一点。

这是一个可以让您入门的工作示例。这不是我会这样做的方式,就像我会在 xaml 中那样,但正如你要求从后面的代码中那样做,你去 :)

附带说明一下,在 Code behind 中定义模板几乎总是一个坏主意,尽量避免它。

Windows.xaml

<Window x:Class="StackOverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:StackOverflow"
    Title="Super long title of the super window" Width="500" Height="300">

    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Entity}">
            <TextBlock Text="{Binding Id}" FontSize="{Binding Size}" />
        </DataTemplate>
    </Window.Resources>

    <local:MyTabControl x:Name="tabControl" ItemsSource="{Binding Entities}" />

</Window>

窗口.xaml.cs

using System.Windows;
using System;
using System.Windows.Data;
using System.Collections.Generic;
using System.Windows.Controls;

namespace StackOverflow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public IEnumerable<Entity> Entities
    {
        get
        {
            for (int i = 0; i < 5; i++)
            {
                yield return new Entity() { Id = i };
            }
        }
    }
}

public class MyTabControl : TabControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        var tabitem = base.GetContainerForItemOverride() as TabItem;
        if (tabitem != null)
        {
            tabitem.Loaded += OnTabItemLoaded;
        }
        return tabitem;
    }

    void OnTabItemLoaded(object sender, RoutedEventArgs e)
    {
        var tabItem = sender as TabItem;
        if (tabItem == null)
            throw new InvalidOperationException();
        tabItem.SetBinding(TabItem.HeaderProperty, new Binding("DisplayName"));
    }
}

public class Entity : DependencyObject
{
    public int Id { get; set; }
    public string DisplayName { get { return "Entity ID : " + Id; } }
}
}
于 2012-10-26T11:34:56.627 回答
1

几件事...

作为 WPF 设计人员和开发人员,XAML 是 GUI 和代码隐藏的最佳方式。它不会以任何方式降低我对 WPF 的理解。所以我推荐 XAML。

相信我自己是一名 Winforms / ASP.NET 开发人员,我最初不愿意使用 XAML,但是我必须编写大量的代码以及各种 GUI 元素之间的关系,以及驯服称为Templates\ Styles\的野兽Triggers,然后ResourceDictionaries只使用背后的 C# 代码对我来说只是一种折磨。

我的经验足够了,这是关于你的问题!

回答你的问题,你设置了_tabControl.ItemsSource吗?并确保其中的每个项目都ItemsSource具有EntityID属性。您的代码应该可以工作。

如果这仍然不起作用,请尝试在 Visual Studio 的Output窗口中查看是否有任何绑定错误。

于 2012-10-26T11:36:49.590 回答