Closed TWhidden closed 1 year ago
@TWhidden Is there a particular reason you want to control the template on the TabItem
rather than on the TabControl
? Only use case I can see is if you want each tab content rendered differently, but then I would probably just handle that in a template selector at the TabControl
level.
What I am hinting at, is that the control template for the TabControl
uses the ContentStringFormat
, ContentTemplate
, and ContentTemplateSelector
properties of the TabControl
itself on the ContentPresenter
displaying the selected tab content.
So I think something like this would solve your problem (unless each tab should be rendered with different templates)?
<TabControl ContentTemplate="{StaticResource TabCustomTemplate}">
... resources and items from your sample ...
</TabControl>
@nicolaihenriksen - Correct - just managing templates in a resource and applied directly to each TabItem
(same datatype, different collections in my case). I believe but have not verified that the original TabItem
style supported it. When we moved our TabControl
over to MaterialDesign, I failed to notice the template wasn't being applied so I was researching a bug report which got me here. I'm ok with switching to a ContentTemplateSelector
but figured I should report that the potentially breaking side of this. My alternate work around but placing it in a ContentControl
worked for me also. Just a little muddied up.
Out of curiosity, I attempted to trace the theme to understand why the {TemplateBinding ContentTemplate} does not retrieve the template from the TabItem
. While debugging in the Demo App, I ran out of time and couldn't find the exact reason. Could you provide me with a hint as to why this feature is not utilized? The TabItem
control has always intrigued me in WPF.
@TWhidden So your comment got me curious and I had to go play around with it :-)
You are correct, the original default style for a TabControl
does honor this, and therefore so should MDIX I believe. So this is a bug (see my findings at the end of my comment).
To answer your question: {TemplateBinding ContentTemplate}
does not retrieve the template from the TabItem
because when you boil it down, a TemplateBinding
is just a Binding
where the source is predefined to be the control for which you are currently defining a ControlTemplate
. Thus it can only be used inside the <ControlTemplate/>
element, and will always refer to the control being templated, as the source. If you want a different source, you can use a normal Binding
and the various options available in the RelativeSource
property. I this case however, the TabItem
is actually a child of the TabControl
and thus you cannot easily do it in this manner.
What I came to find, which was actually something I had not stumbled upon before, is that the TabControl
actually exposes these properties: TabControl.SelectedContentStringFormat
, TabControl.SelectedContentTemplate
, and TabControl.SelectedContentTemplateSelector
alongside the TabControl.SelectedContent
property. And these actually do exactly what we desire. They first inspect the selected TabItem.ContentXyz
property and if that is not set, it checks the corresponding TabControl.ContentXyz
property. So the conclusion is that this is an actual bug and I will create a PR with a UI test that proves it (i.e. fails without the required changes) along with the simple fix of adding the "Selected" prefix to the bindings in the link from my previous comment.
@nicolaihenriksen - Sweet, well sorry for the extra work added. And also, thanks for the callout on the 4.9 release.
Bug explanation
The
TabItem
control does not allow you to set aContentTemplate
For example, if added to the Demo app:
with this small amount added to the
TabsViewModel
:In my case, I have a collection of data that shows up in each tab - results look like this:
Expected result is to use the
ContentTemplate
supplied on theTabItem
I have not tried using a
ContentTemplateSelector
as of yet - the forcing of theContentTemplate
should have handled the collection correctly.The MaterialDesign source style looks correct as far as I can tell.
If I remove the
ContentTemplate="{StaticResource TabCustomTemplate}"
from the TabItem, the result is the same as if the ContentTemplate just is not being honored.A work around I found is to inject the results into a ContentControl like this:
which correctly rendered the results
For now Ill use my work around, but hoping if you can tell me if I am doing it wrong or this should work.
Thanks!
Version
4.9.0 (doing it also on previous versions so not new to 4.9 or anything)