wpf - 没有 ItemsSource 的 TabControl ItemTemplate

标签 wpf data-binding mvvm tabs

我正在使用 TabControl 编写 WPF 应用程序。一开始,我有一个 TabControl 绑定(bind)到 TabBase 项的 ObservableCollection,其中 TabBase 是选项卡 View 模型的基类:

<TabControl
    IsSynchronizedWithCurrentItem="True"
    ItemsSource="{Binding Tabs}"
    ItemTemplate="{StaticResource ClosableTabTemplate}"
...
public ObservableCollection<TabBase> Tabs { get; private set; }
...
public abstract class TabBase : ViewModelBase
...
public abstract class ViewModelBase : INotifyPropertyChanged
{
    public virtual string DisplayName { get; protected set; }
...
<DataTemplate x:Key="ClosableTabTemplate">
    <DockPanel Width="120">
        <Button
            Command="{Binding Path=CmdClose}"
            Content="X"
            />
        <ContentPresenter 
            Content="{Binding Path=DisplayName}">
        </ContentPresenter>
    </DockPanel>
</DataTemplate>

但是当我切换选项卡时,我遇到了一个问题,似乎每次都会创建当前选项卡,即使它之前已经打开过。通过 StackOverflow 搜索我找到了解决方案 here引用here 。我已将声明性 ItemsSource 的使用替换为从代码动态创建选项卡。选项卡切换性能问题已解决,但选项卡标题已丢失到模板的链接,因此我看到的不是带有标题和关闭按钮的选项卡标题,而是一个没有任何内容的小选项卡标题。玩了一下选项卡创建代码,我能够恢复选项卡大小和关闭按钮,但没有绑定(bind) - 没有标题和关闭按钮不起作用(5 行 item.Header 恢复了原始选项卡大小):

    private void AddTabItem(TabBase view)
    {
        TabItem item = new TabItem();
        item.DataContext = view;
        item.Content = new ContentControl();
        (item.Content as ContentControl).Focusable = false;
        (item.Content as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding());

        item.Header = new ContentControl();
        (item.Header as ContentControl).DataContext = view;
        (item.Header as ContentControl).Focusable = false;
        (item.Header as ContentControl).SetBinding(ContentControl.ContentProperty, new Binding());
        item.HeaderTemplate = (DataTemplate)FindResource("ClosableTabTemplate");

        tabControl.Items.Add(item);
    }

问题是,如何在没有 ItemsSource 绑定(bind)的情况下使 ItemTemplate 适用于 TabControl?

最佳答案

当您将 item.Header 显式设置为 ContentControl 时,HeaderTemplate 现在使用该对象作为其 DataContext。通常,Header 属性将获取您的 ViewModel,而 ContentPresenter 将获取该(非可视)对象并将 HeaderTemplate 应用于它。现在,您已将 ViewModel 在层次结构中下推了一个级别,因此模板不会与数据应用在同一位置。移动其中之一应该可以解决绑定(bind)问题,但其中之一可能更适合您的情况:

item.Header = view;

(item.Header as ContentControl).ContentTemplate = (DataTemplate)FindResource("ClosableTabTemplate");

关于wpf - 没有 ItemsSource 的 TabControl ItemTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9592767/

相关文章:

c# - Bgr32 PixelFormat 中的第四个 channel 是什么

wpf - MahApps.Metro - 无法设置 TextBox ClearTextButton 字体系列

wpf - 不实现 IValueConvert.ConvertBack 时的最佳实践

wpf - DataGrid表显示额外的不必要的空行

javascript - Knockout.js - 如何更改 View 模型

wpf - 如何解决 MVVM 范式中的以下设计? (新)

c# - 组合框上的 IsEditable 没有效果

android - 如何因数据绑定(bind)的 safeUnbox 警告而导致构建过程失败

c# - 似乎无法在我的脑海中获得 WPF DataBinding

java - 在 Viewmodel 中访问 BroadCastReceiver