简体   繁体   English

如何在WPF TabControl中以编程方式更改选项卡名称?

[英]How do I programatically change tab names in a WPF TabControl?

All, 所有,

I have searched extensively for the solution here but I have a feeling my problem stems from a basic lack of knowledge about WPF. 我已经在这里广泛地搜索了解决方案,但是我感到我的问题是由于对WPF的基本了解而引起的。 I am new to it and have thus far hacked and Googled my way through as best I can. 我是新手,到目前为止,我已尽其所能入侵并搜寻了Google。

Basically, I have a Ribbon dynamically interacting with a TabControl. 基本上,我有一个功能区与TabControl动态交互。 The Ribbon tabs select a category of items, the MenuItems in the RibbonGroups then choose an item within the category. 功能区选项卡选择项目的类别,RibbonGroups中的MenuItems然后选择类别中的项目。 Upon clicking an item, the tabs on the TabControl need to dynamically change. 单击项目后,TabControl上的选项卡需要动态更改。 Whether that is just the Headers, the tabs themselves, or the entire TabControl is fine with me. 无论是标题,选项卡本身还是整个TabControl,我都可以接受。 Thus far, upon clicking a MenuItem on the inside one of the RibbonGroups, I attempt to just set the Header text equal to "blah" for each tab on the TabControl. 到目前为止,单击功能区组之一内部的MenuItem时,我尝试仅将TabControl上每个选项卡的Header文本设置为等于“ blah”。 Then the Header object throws a null pointer. 然后,Header对象将引发空指针。 This is what happens whether I set the Header, the Tabs, or the TabControl itself. 无论我设置标题,选项卡还是TabControl本身,都会发生这种情况。

Why?!?!?!? 为什么?!?!?!?

...and how in the world do I fix it??? ...以及如何解决这个问题???

Thanks! 谢谢!

WPF is designed with data/UI separation in mind. WPF在设计时考虑了数据/ UI分离。 One of the reasons you're having trouble finding a solution is because what you're trying to do is a no-no; 您无法找到解决方案的原因之一是因为您尝试做的事是不对。 instead of programmatically changing the UI's header text, you should be changing the underlying data instead, and allowing the WPF plumbing to update how the data is displayed. 而不是通过编程方式更改UI的标题文本,而应更改基础数据,并允许WPF管道更新数据的显示方式。

A WPF tab control can literally contain any type of object; WPF选项卡控件可以从字面上包含任何类型的对象。 you could fill it with integers or strings or FooBars or whatever. 您可以用整数或字符串或FooBars或其他填充它。 There's no guarantee that any of these objects will define a Header property, and it's up to the developer to configure data bindings or templates which instruct the TabControl just how a FooBar or a whatever should be displayed. 不能保证这些对象中的任何一个都将定义Header属性,并且由开发人员配置数据绑定或模板,这些数据绑定或模板指示TabControl如何显示FooBar或其他内容。

In an ideal WPF application which adheres to the MVVM design pattern, you might have your TabControl bound to a collection of view models which each define a HeaderText property. 在遵循MVVM设计模式的理想WPF应用程序中,您可以将TabControl绑定到视图模型的集合,每个视图模型都定义一个HeaderText属性。 Your view models would implement the INotifyPropertyChanged interface so that when the HeaderText property was changed on the view model then the UI would get updated. 您的视图模型将实现INotifyPropertyChanged接口,以便在视图模型上更改HeaderText属性后,UI将会更新。

Having said all that, if you've got an existing application it may be unrealistic to rewrite it from scratch using a different design pattern, and MVVM is not easily added on to an existing code base. 说了这么多,如果您已有一个现有的应用程序,则使用不同的设计模式从头开始重写它可能是不现实的,并且MVVM不容易添加到现有的代码库中。 If you're working with simple Designer generated UI without using any data binding, then the following code does what you ask. 如果您在使用简单的Designer生成的UI而不使用任何数据绑定,那么以下代码将满足您的要求。 Sometimes. 有时。

foreach(TabItem item in tabControl.Items)
    item.Header = "blah";

... but as I said before, there's no guarantee that a WPF TabControl's Items collection will contain items of type TabItem, so this code is not safe. ...但是,正如我之前所说,不能保证WPF TabControl的Items集合将包含TabItem类型的项目,因此此代码并不安全。

While RogerN's answer is probably a better answer, here is a code sample that changes the text that appears on a tab: 尽管RogerN的答案可能是一个更好的答案,但是下面的代码示例更改了选项卡上显示的文本:

XAML: XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <TabControl Name="MyTabControl">
        <TabItem Header="Tab One">
            <TextBlock Text="This is tab #1." />
        </TabItem>
        <TabItem Header="Tab Two">
            <TextBlock Text="This is tab #2." />
        </TabItem>
        <TabItem Header="Tab Three">
            <TextBlock Text="This is tab #3." />
        </TabItem>
    </TabControl>
    <Button Grid.Row="1" Content="Change Tab" Name="ChangeButton" Click="ChangeButton_Click" />
</Grid>

Code behind: 后面的代码:

public partial class MainWindow : Window {

    public MainWindow() {
        InitializeComponent();
    }

    private void ChangeButton_Click(object sender, RoutedEventArgs e) {
        ((TabItem)MyTabControl.Items[0]).Header = "Changed!";
    }
}

Try binding it to a list in the code like so: 尝试将其绑定到代码中的列表,如下所示:

private List<TabItem> TabItems = new List<TabItem>()
{
    "Item1",
    "Item2",
    "Item3"
};

tabcontrol1.ItemSource = TabItems;

Then rebind it any time you want to change the items in the tabcontrol. 然后,只要您想更改tabcontrol中的项目,就可以重新绑定它。 This way you can dynamically change names and add more tab items. 这样,您可以动态更改名称并添加更多选项卡项。 In doing this you'll have to programmatically add controls using the TabItem.Content property. 为此,您必须使用TabItem.Content属性以编程方式添加控件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM