[英]Change tabitem style when selected item changes
I have a TabControl
and a style for each of my TabItem
(with a StyleSelector
). 我有一个TabControl
和每个TabItem
的样式(带有StyleSelector
)。 I want each TabItem
to change its style when the selected item changes. 我希望每个TabItem
在所选项目更改时更改其样式。
So I create a TabItemCustom
with a property IsItemAfterSelected
: 所以,我创建了一个TabItemCustom
与属性IsItemAfterSelected
:
public class TabItemCustom: TabItem
{
public static readonly DependencyProperty IsItemAfterSelectedProperty =
DependencyProperty.Register("IsItemAfterSelected",
typeof(bool),
typeof(TabItemCustom),
new PropertyMetadata(false));
public bool IsItemAfterSelected
{
get { return (bool)GetValue(IsItemAfterSelectedProperty ); }
set { SetValue(IsItemAfterSelectedProperty , value); }
}
}
This property has to contain True
if one of the next items is selected. 如果选择了以下一项,则此属性必须包含True
。
I can know when the SelectedIndex
changes with this DataTrigger
: 我可以知道什么时候SelectedIndex
这个变化DataTrigger
:
<sys:Boolean x:Key="StyleValueTrue">True</sys:Boolean>
<DataTrigger Binding="{Binding Path=SelectedIndex, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Mode=TwoWay, Converter={StaticResource ConverterTabItemAriane}}" Value="{StaticResource StyleValueTrue}">
<Setter Property="IsItemAfterSelected" Value="{Binding Converter={StaticResource ConverterTabItemAriane}, RelativeSource={RelativeSource Self}}"/>
</DataTrigger>
I use the same converter to detect if is the SelectedIndex
(if integer always return True
) and to set my value: 我使用相同的转换器来检测是否为SelectedIndex
(如果integer始终返回True
)并设置我的值:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is DependencyObject)
{
DependencyObject container = (DependencyObject)value;
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
var itemIndex = itemsControl.ItemContainerGenerator.IndexFromContainer(container);
if (itemsControl is TabControl)
{
TabControl tabcontrol = (TabControl)itemsControl;
if (tabcontrol.SelectedIndex >= itemIndex) return true;
else return false;
}
}
else if (value is int) return true;// selected index has changed
return false;
}
I've checked with breakpoints: when I change the selected item it goes in the converter and returns True
. 我已经检查了断点:当我更改所选项目时,它将进入转换器并返回True
。 But my Property is set only once on the loading of the TabControl
. 但是我的Property在TabControl
加载时仅设置了一次。 The Trigger
always return the same value why the property is set once? Trigger
总是返回相同的值,为什么属性设置一次?
When I'll be able to set this property my goal is to add a DataTrigger
like this: 当我能够设置此属性时,我的目标是添加一个DataTrigger
如下所示:
<DataTrigger Property="IsItemAfterSelected" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
I don't know if my approach is the easiest but I didn't found a better solution (I've tried removing StyleValueTrue
and put True
instead but same result). 我不知道我的方法是否最简单,但是我没有找到更好的解决方案(我尝试删除StyleValueTrue
并放入True
但结果相同)。
Any thoughts to solve this? 有什么想法可以解决这个问题?
If you want to do it with Binding
s: 如果要使用Binding
来执行此操作:
XAML: XAML:
<Style TargetType="{x:Type local:TabItemCustom}">
<Setter Property="IsItemAfterSelected">
<Setter.Value>
<MultiBinding Converter="{StaticResource ConverterTabItemAriane}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TabControl}}"/>
<Binding RelativeSource="{RelativeSource Self}"/>
<Binding Path="SelectedIndex" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type TabControl}}"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsItemAfterSelected" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
Converter: 转换器:
public class ConverterTabItemAriane : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
TabControl tabControl = values[0] as TabControl;
TabItem tabItem = values[1] as TabItem;
if (tabControl != null && tabItem != null && values[2] is int)
{
var selectedIndex = (int)values[2];
var itemIndex = tabControl.ItemContainerGenerator.IndexFromContainer(tabItem);
return selectedIndex >= itemIndex;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
If you want to do it inside your TabControl
: 如果要在TabControl
内执行此操作:
XAML: XAML:
<Style TargetType="{x:Type local:TabItemCustom}">
<Style.Triggers>
<Trigger Property="IsItemAfterSelected" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
TabControl: TabControl的:
public class TabControlCustom : TabControl
{
protected override System.Windows.DependencyObject GetContainerForItemOverride()
{
return new TabItemCustom();
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
int i = 0;
foreach (var item in Items)
{
var tabItem = ItemContainerGenerator.ContainerFromItem(item) as TabItemCustom;
if (tabItem != null)
{
tabItem.IsItemAfterSelected = SelectedIndex >= i;
}
i++;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.