2

I have a CustomTabItem in a custom controls library. When I explicitly use it in xaml or in code, it works. When I use the binding to ViewModel (CaliburnMicro) instead of my control, the standard TabItem is used. How to specify the use of CustomTabItem in xaml?
I tried to specify DataType = "{x:Type adc:ActorTabItem}" - did not work.

I tried to specify DataType="{x:Type adc:CustomTabItem}" - did not work.

        <adc:TabControl ItemsSource="{Binding Pages}" Grid.Row="1">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"></TextBlock>
                </DataTemplate>
            </TabControl.ItemTemplate>

            <adc:TabControl.ContentTemplate>
                <DataTemplate>
                    <ContentControl cal:View.Model="{Binding}" />
                </DataTemplate>
            </adc:TabControl.ContentTemplate>
        </adc:TabControl>
Oram
  • 1,589
  • 2
  • 16
  • 22
Yury Yatskov
  • 175
  • 2
  • 7
  • You may need to subclass the TabControl and override its [`ItemContainerGenerator` property](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.itemscontrol.itemcontainergenerator?view=netframework-4.8), to return your own ItemContainerGenerator object that creates instances of your subclass. Unfortunately, WPF doesn't seem to have provided a way to plug that in without subclassing the parent (this is the same for ListBox, ItemsControl, etc.). – 15ee8f99-57ff-4f92-890c-b56153 May 08 '19 at 19:34
  • Thank you. Considered the inside of the ItemContainerGenerator property and the methods ContainerFromItem (Object) and ContainerFromIndex (Int32). Inside a common mechanism without reference to the class TabItem. Change did not become this property. This path led me to the GetContainerForItemOverride and IsItemItsOwnContainerOverride methods of the TabControl class. I redefined these methods in the subclass and I received a positive result. Below is the code: – Yury Yatskov May 13 '19 at 08:58
  • protected override bool IsItemItsOwnContainerOverride(object item) { return (item is ActorTabItem); } protected override DependencyObject GetContainerForItemOverride() { return new ActorTabItem(); } – Yury Yatskov May 13 '19 at 09:01
  • Next, I ran into another problem where my CustomTabItem has no parent, and the children (items) for TabControl have a view model. But it will be another question if I do not decide. – Yury Yatskov May 13 '19 at 09:44
  • 1) Please add your classes to your question so I can figure out what the parent thing is all about. 2) Children having a viewmodel should not be a problem at all (except for [this issue that you may not have run into yet](https://stackoverflow.com/questions/9794151/stop-tabcontrol-from-recreating-its-children)). Why do you think the viewmodel is an issue? – 15ee8f99-57ff-4f92-890c-b56153 May 13 '19 at 13:33
  • 1) For more understanding, I created an example and located here https://github.com/YuryYatskov/PeopleDemo . – Yury Yatskov May 13 '19 at 20:34
  • 2) Previously, I did not encounter this problem, but it seems that I now have it.In my example, I added the functionality of dragging bookmarks in the library's program code.When I do not use the binding in ItemsSource then everything works. When I use binding to view model, then dragging does not work. Therefore, the view model is an issue. – Yury Yatskov May 13 '19 at 20:35
  • I think I need to inform the library about the need for shuffling. At the application level, implement a change in an ItemsSource. Possible to override the ItemsSource property. – Yury Yatskov May 13 '19 at 20:38
  • Overriding ItemsSource is not a good idea. You don’t have any problems with ItemsSource. What is a “Binding in ItemsSource”? I’ll have to look at your drag and drop code. Dragging and dropping collection items is a solved problem, if I correctly understand what you’re doing. – 15ee8f99-57ff-4f92-890c-b56153 May 13 '19 at 21:21
  • Your drop is broken if you’re creating tab items from a collection of viewmodels bound to TabControl.ItemsSource. Do not touch Items. Always, when there’s a bound collection, alter the collection itself. Add, remove, reorder the viewmodels. Let the TabControl (or ComboBox or whatever) update UI accordingly. See: https://stackoverflow.com/a/48064086/424129 – 15ee8f99-57ff-4f92-890c-b56153 May 13 '19 at 21:39
  • Yes, I can change the ItemsSource collection itself. Changed the example, the ItemsSource upcasted to the IList. It works. Please give a short answer to this question so that I can mark it as correct. Thank! – Yury Yatskov May 14 '19 at 18:48

1 Answers1

1

You can do what you want easily. Just override the GetContainerForItemOverride method as following

public class TabControlEx : TabControl
{

    protected override DependencyObject GetContainerForItemOverride()
    {
        return new TabItemEx();
    }
}
  • Yes, I did it and it worked. For completeness, I also redefined ```lang-csharp protected override bool IsItemItsOwnContainerOverride(object item) => item is TabItemEx; ``` – Yury Yatskov Dec 09 '20 at 06:29