【问题标题】:Styling data bound TabControl样式数据绑定 TabControl
【发布时间】:2014-09-01 11:32:10
【问题描述】:

我有一个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}"/>

谁能帮助我,以便在标签绑定数据时实现上述目标?

干杯。

【问题讨论】:

    标签: wpf xaml tabcontrol


    【解决方案1】:

    我使用了 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;
        }
    }
    

    结果你得到

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

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

    【讨论】:

    • 言语无法描述您的帮助。这就像一个魅力。非常感谢
    【解决方案2】:

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

    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"];
    }
    

    更新>>>

    既然您终于告诉我们您正在使用 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? 问题的回答中找到使用附加属性和其他有用链接包装事件的示例。

    【讨论】:

    • 那是一个很好的。我可能应该在我的帖子中提到这一点,但我使用的是 MVVM 模式。有没有办法将选择更改事件发送到视图模型,然后在那里进行处理?
    • 我可能应该在我的帖子中提到这一点,但我使用的是 MVVM 模式...没有可能...你应该已经提到了。你会不告诉他们颜色就去买车吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    相关资源
    最近更新 更多