Вдохновленный this answer Я создал прикрепленное свойство, которое позволяет мне извлечь высоту панели вкладок. Я использую это значение для создания поля, необходимого для моего наложения. Я предпочитаю эту версию, потому что
- не должны создать новый стиль/изменить стиль по умолчанию
- Не нужно создать новый элемент управления только для одного маленького аспекта
Вот код для прикрепленного свойства.
public static class TabPanelHeaderHeight
{
private const double InitialValue = -1.0;
private static readonly DependencyProperty HeaderHeightProperty =
DependencyProperty.RegisterAttached(name: "HeaderHeight", propertyType: typeof(double), ownerType: typeof(TabPanelHeaderHeight),
defaultMetadata: new FrameworkPropertyMetadata(defaultValue: InitialValue, flags: FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, propertyChangedCallback: OnHeaderHeightChanged));
public static double GetHeaderHeight(UIElement element)
{
return (double)element.GetValue(HeaderHeightProperty);
}
public static void SetHeaderHeight(UIElement element, double value)
{
element.SetValue(HeaderHeightProperty,value);
}
private static void OnHeaderHeightChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
var target = obj as TabControl;
if (target == null)
return;
// we hijack the on value changed event to register our event handler to the value we're really interested in
// but we want to do this only once, so we check if the value is the (invalid) initial value and change the value afterwards to register the event listener only once.
if ((double)args.OldValue == InitialValue)
{
var tp = target.GetChildOfType<TabPanel>();
tp.SizeChanged += (sender, eventArgs) => { TargetSizeChanged(target,tp); };
TargetSizeChanged(target,tp);
}
}
private static void TargetSizeChanged(TabControl target, TabPanel tp)
{
SetHeaderHeight(target, tp.ActualHeight);
}
public static T GetChildOfType<T>(this DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
}
GetChildOfType
помощник от this post
Он может быть использован в XAML как это:
<TabControl yourNs:TabPanelHeaderHeight.HeaderHeight="{Binding Path=HeaderHeight}" >
...
Либо использовать преобразователь значений, чтобы создать запас для наложения или сделать это в посмотреть модель.
Ваше решение работает, но для меня это немного «слишком много» для этой простой задачи. Тем более, что я не смог найти шаблон управления TabControl по умолчанию для .net 4.5. – Onur
Проблема в том, что нет простого способа привязки к TabPanel внутри TabControl, чтобы убедиться, что это фактическая высота ... чего вы действительно хотите достичь? Другой подход может заключаться в создании пользовательской реализации TabControl, которая предоставляет высоту TabPanel. Я добавлю еще один ответ. – olitee