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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17411972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:07:16  来源:igfitidea点击:

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

c#wpftabcontrolribbon

提问by unwrittenrainbow

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. I am new to it and have thus far hacked and Googled my way through as best I can.

我在这里广泛搜索了解决方案,但我感觉我的问题源于对 WPF 的基本缺乏了解。我是新手,到目前为止,我已经尽我所能进行了黑客攻击和谷歌搜索。

Basically, I have a Ribbon dynamically interacting with a TabControl. The Ribbon tabs select a category of items, the MenuItems in the RibbonGroups then choose an item within the category. Upon clicking an item, the tabs on the TabControl need to dynamically change. Whether that is just the Headers, the tabs themselves, or the entire TabControl is fine with me. 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. Then the Header object throws a null pointer. This is what happens whether I set the Header, the Tabs, or the TabControl itself.

基本上,我有一个功能区与 TabControl 动态交互。Ribbon 选项卡选择一个项目类别,RibbonGroups 中的 MenuItems 然后选择类别中的一个项目。单击项目后,TabControl 上的选项卡需要动态更改。无论是标题、选项卡本身,还是整个 TabControl 都适合我。到目前为止,在单击 RibbonGroups 内部的 MenuItem 时,我尝试仅将 TabControl 上的每个选项卡的标题文本设置为等于“blah”。然后 Header 对象抛出一个空指针。无论我设置 Header、Tabs 还是 TabControl 本身,都会发生这种情况。

Why?!?!?!?

为什么?!?!?!?

...and how in the world do I fix it???

......我到底该如何修复它???

Thanks!

谢谢!

回答by RogerN

WPF is designed with data/UI separation in mind. 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.

WPF 在设计时考虑了数据/UI 分离。您在寻找解决方案时遇到困难的原因之一是因为您尝试做的是一个禁忌;而不是以编程方式更改 UI 的标题文本,您应该改为更改基础数据,并允许 WPF 管道更新数据的显示方式。

A WPF tab control can literally contain anytype of object; you could fill it with integers or strings or FooBars or whatever. 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.

WPF 选项卡控件实际上可以包含任何类型的对象;你可以用整数或字符串或 FooBars 或其他任何东西来填充它。不能保证这些对象中的任何一个都将定义一个 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. 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.

在遵循 MVVM 设计模式的理想 WPF 应用程序中,您可能将 TabControl 绑定到视图模型的集合,每个视图模型都定义了一个 HeaderText 属性。您的视图模型将实现 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. If you're working with simple Designer generated UI without using any data binding, then the following code does what you ask. Sometimes.

话虽如此,如果您有一个现有的应用程序,使用不同的设计模式从头开始重写它可能是不切实际的,并且 MVVM 不容易添加到现有代码库中。如果您在不使用任何数据绑定的情况下使用简单的设计器生成的 UI,那么以下代码将满足您的要求。有时。

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 类型的项目,因此此代码不安全。

回答by Steve

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!";
    }
}

回答by DanteTheEgregore

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. 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.

然后在您想要更改 tabcontrol 中的项目时重新绑定它。通过这种方式,您可以动态更改名称并添加更多选项卡项。为此,您必须使用 TabItem.Content 属性以编程方式添加控件。