带有 DataTemplate 的 WPF TabControl 行为很奇怪

标签 wpf silverlight xaml datatemplate tabcontrol

如果您将控件放在 DataTemplate 中,为什么它们各自的状态会复制或反射(reflect)在 TabControl 中的每个选项卡中?你在一个选项卡中更改它,所有其他选项卡都会反射(reflect),这是为什么呢?!在我看来,TabControl 仅初始化一个模板化的 ContentControl,并且每次单击 Tab 都会重新复制其中的全部内容 - 保持旧的 controlstates 不变。要了解我的意思,请考虑将其放入您的 XAML-Pad 中:

<TabControl>
  <TabControl.ContentTemplate>
    <DataTemplate>
      <Border>
        <TextBox Text="test"/>
      </Border>
    </DataTemplate>
  </TabControl.ContentTemplate>
  <TabItem Header="Tab1"/>
  <TabItem Header="Tab2"/>
</TabControl>

它将创建一个带有两个模板选项卡的 TabControl。现在在 TextBox 中输入一些内容并切换到另一个 Tab,输入的文本将继续存在。现在每个选项卡都将具有相同的内容。我没有在 ListBox 或任何其他控件中观察到相同的行为,它使实际工作变得非常困难,因为每一点都需要绑定(bind)到 ViewModel 以使其在 TabControl 中可用。当我在 DataTemplate 中使用的扩展器在我的所有选项卡中弹出打开时,我注意到了这种奇怪的行为,尽管我特别提到了一个。作为一种解决方法,我必须将“IsExpanded”绑定(bind)到 ViewModel 中的一个属性,但这样做真的很糟糕。

有谁知道这里发生了什么?

解决方案
<TabControl x:Name="MainTab" SelectedIndex="0"/>
...
Collection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Collection_CollectionChanged);
...
void Collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        TabItem MyNewItem = new TabItem();
        ContentPresenter MyContentPresenter = new ContentPresenter();
        MyContentPresenter.ContentTemplate = (DataTemplate)this.FindResource("MyTemplate");
        MyContentPresenter.Content = e.NewItems[0];
        MyNewItem.Content = MyContentPresenter;                
        MainTab.Items.Add(MyNewItem );
    }
}

最佳答案

行为是完美的,有办法解决这个问题。 DataTemplate 必须仅在绑定(bind)的情况下使用。当您将可枚举项源分配给选项卡控件时,您的数据模板应该并且将包含一种或两种方式绑定(bind)。如果是文本框,应该是双向绑定(bind)。

TabControl 这样做是为了节省内存,在数据模板的情况下,切换选项卡时控件保持不变,但底层绑定(bind)的数据上下文发生了变化,绑定(bind)反射(reflect)了正确的数据。所以在视觉上你会感觉到选项卡发生了变化,但实际上只有数据发生了变化,但控制保持不变。这称为 ui 虚拟化。

在您的情况下,除非您将某些内容绑定(bind)到项目源,否则不应使用数据模板。否则,您必须使用项目容器样式。

关于带有 DataTemplate 的 WPF TabControl 行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7703145/

相关文章:

c# - 从文本框复制后,重音字符无法正确显示

c# - 在CodeBehind中获取ListViewItem控件

silverlight - Name 和 x :Name? 有什么区别

java - Silverlight/Java Applet 等效项?

wpf - 如何使用 XAML 中的选定值制作简单的组合框?

c# - 如何获取非绑定(bind) WPF 组合框来显示所选项目而不是 {System.Windows.Controls.ComboBoxItem :

wpf - 如何在 Prism-Unity-WPF 应用程序中正确处理 ContainerControlledLifetimeManager 创建的依赖项

水平方向的WPF TreeView?

silverlight - 在Silverlight编程中,如何防止访问者缓存下载的内容?

c# - 获取列表框选定的项目