The following only ever creates one instance of MyTabView
. I've confirmed this by putting a breakpoint in the constructor in MyTabView.xaml.cs. The view is displayed in a tab, and however many tabs I create, I only ever hit that constructor once.
<DataTemplate DataType="{x:Type vm:MyTabViewModel}" x:Shared="false">
<vw:MyTabView />
</DataTemplate>
Tab control:
<TabControl
Grid.Row="1"
ItemsSource="{Binding Tabs}"
SelectedItem="{Binding SelectedTab}"
>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl>
This causes all the tabs to reflect share any state that's not bound to a view model: If you move a GridSplitter
, that's the same GridSplitter
in all the other tabs, so it appears to the user that you moved all of them. It's absurd.
I don't understand. Is there any way to use TabControl
with multiple items of the same type?
EDIT: Added x:Shared="false"
to DataTemplate
.
UPDATE:
So I've found a couple of fixes, but I don't like them very much. I'm going to take a look at writing a Converter that converts ObservableCollection<Object>
to ObservableCollection<TabItem>
-- kind of like a live-updated version of
coll.Select(vm => new TabItem() { Content = vm });
...but we'll see whether or not it likes getting TabItem
instances from ItemsSource
. My money says don't bet on it. But we'll see.
UPDATE 2: Took a while to get back to this. The gimmick with swapping in a collection of tab items works, though SelectedItem
is problem. Turns out there's another solution (below) that doesn't create that issue, and also avoids the complexity and goofiness of creating a "middleman" collection that has to mirror changes in the source collection.
Try adding an
x:Shared="false"
attribute to your template.