样式数据绑定TabControl

时间:2014-09-01 11:32:10

标签: wpf xaml tabcontrol

我有TabControl数据绑定到ObservableCollection,如下面的

<TabControl  HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch" 
        Style="{DynamicResource BreadCrumbTabControl}" 
        ItemsSource="{Binding SalesItem.DispayedCategory}" 
        SelectedIndex="{Binding SalesItem.TabIndex}">

    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayText}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <-- user control -->
        </DataTemplate>
    </TabControl.ContentTemplate>

</TabControl>

我想设置标签的样式,以便第一个标签具有不同的样式,而其他标签将具有另一种样式。如果没有数据绑定,我知道该怎么做。

<TabItem Header="Page 1" Style="{DynamicResource FirstTabItem}" />
<TabItem Header="Page 2" Style="{DynamicResource NormalTabItem}"/>

任何人都可以帮助我,所以我可以在标签数据绑定的情况下实现上述目标吗?

干杯。

2 个答案:

答案 0 :(得分:2)

我使用了ItemContainerStyleSelector

    <Window.Resources>
    <Style x:Key="first" TargetType="TabItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TabItem">
                    <Border Background="CadetBlue" Height="50" Width="50">
                        <TextBlock Text="{Binding}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="others" TargetType="TabItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TabItem">
                    <Border Background="Red" Height="50" Width="50">
                        <TextBlock Text="{Binding}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <local:StyleSelector x:Key="StyleSelector" FirstStyle="{StaticResource first}" OtherStyles="{StaticResource others}"/>
 </Window.Resources>
    <TabControl ItemsSource="{Binding Lista}" ItemContainerStyleSelector="{StaticResource StyleSelector}"/>

和StyleSelector看起来跟着

public class StyleSelector : System.Windows.Controls.StyleSelector
{
    public Style FirstStyle { get; set; }
    public Style OtherStyles { get; set; }
    private int number;

    public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject container)
    {
        return (number++) == 0 ? FirstStyle : OtherStyles;
    }
}

结果你得到了 enter image description here

如果要更改奇数/偶数tabitem的外观,也可以使用此解决方案。为了获得这个,请做以下更改

 return (number++) % 2 == 0 ? FirstStyle : OtherStyles;

enter image description here

答案 1 :(得分:1)

在检查所选Style是否是您的第一个TabItem之后,您需要处理TabControl.SelectionChanged Event并以编程方式设置TabItem。你可以尝试这样的事情:

private void TabControlSelectionChanged(object sender, SelectionChangedEventArgs args)
{
    TabItem tabItem = ((sender as TabControl).SelectedItem as TabItem);
    if (tabItem.Name == "1stTabItem") tabItem.Style = (Style)Resources["FirstTabItem"];
    else tabItem.Style = (Style)Resources["NormalTabItem"];
}

更新&gt;&gt;&gt;

现在情况发生了变化,因为您最终告诉我们您正在使用MVVM。大多数MVVM开发人员都盲目地想要遵循 no code behind 原则,而根本不理解它。对于像这样的UI相关工作,使用背后的代码绝对没问题,或许比将UI属性放入视图模型更正确。

但是,如果您确实不想使用后面的代码,那么您还有其他一些选择。一个选项是简单地将数据绑定到SelectedItem属性并在属性设置器中执行您的操作,就像我对Selection changed event of combobox in wpf mvvm的回答一样(来自链接的答案):

public SomeType Item 
{
    get { return item; }
    set
    {
        if (item != value)
        {
            item = value;
            NotifyPropertyChanged("Item");
            // New item has been selected. Do something here
        }
    }
}

但是,您无法从视图模型访问Resources集合,因此这对您没什么用处。另一个选择是将所需事件包装在附加属性中,并将Style设置代码放在那里。您可以在我对What's the best way to pass event to ViewModel?问题的回答中找到包含附加属性和其他有用链接的事件的示例。