TabItems TabControl обмениваются тем же контентом... Не хочу
В следующем примере xaml заставляет каждый элемент вкладки использовать один и тот же TextBox. Это имеет смысл, на некотором уровне, я думаю... но это неожиданное поведение, и почти похоже на ошибку. И я не смог найти никакой информации в документах, объясняющей поведение или как правильно обойти это.
<TabControl>
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Name="tab1" />
<TabItem Name="tab2" />
</TabControl>
При переключении между tab1 и tab2 используется один и тот же TextBox, когда я ожидаю новый TextBox для каждой вкладки. Как я могу получить последний случай?
Создание подкласса TabItem и превращение его содержимого в TextBox по умолчанию - это один из способов сделать это, но я просто хочу убедиться, что мне чего-то не хватает.
редактировать
Я понимаю, что установка содержимого явно для каждой вкладки решит проблему, но вкладки должны создаваться динамически. Я хочу использовать шаблон содержимого, чтобы я мог добавлять новые вкладки с помощью привязки данных и не делить содержимое, так как оно вызывает странное поведение.
Возможно, с текущей реализацией TabControl, не существует декларативного подхода к решению этой проблемы. Это довольно тривиальная настройка содержимого в коде, но такие вещи всегда чувствуются неправильно в WPF. Мне кажется, что это неоправданная оптимизация TabControl; это должно быть по крайней мере необязательно для ситуаций, когда это нецелесообразно.
3 ответа
Я подозреваю, что есть более хороший способ добиться того, чего вы пытаетесь достичь, но я думаю, что это сработает (проверю, но я использую Linux Atm):
<TabControl>
<TabControl.Resources>
<Style TargetType="TabItem" x:Shared="False">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBox />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Name="tab1" />
<TabItem Name="tab2" />
</TabControl>
Это будет работать, если вы определите usercontrol, в котором есть содержимое вкладки. Я создал следующий usercontrol:
<UserControl x:Class="SO_Testing.TextBoxUC"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox/>
</Grid>
</UserControl>
Затем я изменил свой xaml окна, чтобы он был таким:
<Window x:Class="SO_Testing.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SO_Testing"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl>
<TabItem Name="tab1" Header="Test">
<local:TextBoxUC/>
</TabItem>
<TabItem Name="tab2" Header="Test 2">
<local:TextBoxUC/>
</TabItem>
</TabControl>
</Grid>
</Window>
Это может быть не совсем то, что вам нужно, но, по крайней мере, макет каждой вкладки определяется только в одном месте, и вы можете назначить текстовый текст для каждого пользовательского элемента управления, чтобы показать значения для каждой из ваших вкладок.
У меня была та же проблема, и я нашел этот пост, объясняющий, почему это происходит и как обойти это. Это ссылка на тот случай, если кто-то еще столкнется с той же проблемой:
http://www.codeproject.com/Articles/460989/WPF-TabControl-Turning-Off-Tab-Virtualization