I have a TabControl, and I want to do the following:
- Take first and last of the
TabItems inTabControl.Items - Get their
Margins - Supply those
Thicknesses to the converter to convert these two structs into final value
Here is a related code showing what I am trying to do:
<Border.Padding>
<MultiBinding Converter="{StaticResource MarginsToPaddingConverter}">
<Binding Path="Margin">
<Binding.Source>
<Binding RelativeSource="{RelativeSource AncestorType=TabControl}" Path="Items" Converter="{StaticResource ItemCollectionToFirstItemConverter}" ConverterParameter="{x:Type TabItem}" />
</Binding.Source>
</Binding>
<Binding Path="Margin">
<Binding.Source>
<Binding RelativeSource="{RelativeSource AncestorType=TabControl}" Path="Items" Converter="{StaticResource ItemCollectionToLastItemConverter}" ConverterParameter="{x:Type TabItem}" />
</Binding.Source>
</Binding>
</MultiBinding>
</Border.Padding>
But I can’t set Binding as RelativeSource or Source of other Binding. Basically the solution at hand is to create converter, which would take TabControl.Items and convert it to the final value, but the problem is I want to animate Margins of both TabItems, so I need to bind specifically to these properties. If I would bind to TabControl.Items, the Border.Padding would not get refreshed if Margin of any TabItem would change. So what should I do?
Update
Ok, so one of the possible solutions is to hook into TabItem.Loaded event, and then use DependencyPropertyDescriptor to hook Changed event on appropriate properties, then hook all items in TabItem.Items collection, hook any new items and automatically unhook all old items, and hook like million other stuff. But this is quite complicated and it’s like 400 LOC. Isn’t there anything simpler? Preferably in pure XAML.
Unfortunately this modified response is not as elegant as I’d like, but it should work.
Basically, use another dummy control as a relay for the binding. Specifically, this scenario arises when you want to pull the first and last of a collection. You can’t just use a converter to grab the first/last and the property all at once, because if you change a property on the first or last item, the converter won’t pick up the change. So you have to do something that melds in with dependency properties – almost like some sort of a second order dependency property would be nice.
Anyways, here’s some code:
And an actual use case:
So the idea here would be to grab the first and last item using the relay control and then bind to there margins.