如果您将控件放在DataTemplate中,为什么它们的各个状态被复制或反映在TabControl中的每个Tab中?你在一个标签中更改它,所有其他标签都反映出来,为什么会这样?!在我看来,TabControl只初始化一个模板化的ContentControl,每次点击Tab都会重新复制整个内容 - 让旧的控制状态保持不变 . 看看我的意思是考虑把它放在你的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或任何其他控件中观察到相同的行为,它使得实际工作非常困难,因为每一点都需要绑定到ViewModel以使其在TabControl中可用 . 当我在DataTemplate中使用的Expanders在我的所有选项卡中弹出时,我注意到这种奇怪的行为,尽管我专门解决了一个问题 . 作为一种解决方法,我必须将“IsExpanded”绑定到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 );
}
}
2 回答
行为是完美的,有一种方法可以解决这个问题 . 必须仅在绑定时使用DataTemplate . 将可枚举项目源分配给选项卡控件时,您的数据模板应该包含一个或两个方式的绑定 . 如果是文本框,则应该是双向绑定 .
TabControl执行此操作以节省内存,在数据模板的情况下,切换选项卡时控件保持不变,但是底层绑定的datacontext是更改的,绑定反映了正确的数据 . 因此,您可以在视觉上看到标签已更改,但实际上只有数据更改,但控制保持不变 . 这称为ui虚拟化 .
在您的情况下,除非将某些内容绑定到项目源,否则不应使用数据模板 . 否则,您必须使用项目容器样式 .
WPF中的TabControls有点令人讨厌 . 例如,当您切换选项卡时,它会破坏第一个选项卡上的所有内容,并加载第二个选项卡的控件 . 唯一没有被破坏/重新创建的是所有选项卡上存在的控件,例如在TabItem的模板中创建的TextBox .
因此,您的TextBox在其他选项卡上被重复使用,并且由于TextBox.Text未绑定到任何内容,因此在切换选项卡时它保持不变 .
要更改此行为,请将TextBox.Text值绑定到某个值,或者使用它自己的TextBox版本创建每个TabItem .