TabItem和TabContent模板根据属性值更改

时间:2013-12-21 19:12:21

标签: .net wpf templates tabcontrol tabitem

我在WPF .Net中有一个TabControl项目,其中包含2个内容模板和2个用于tabitems的模板。我将自己的对象绑定为ItemsSource,它有两个属性:

public bool IsPrivMsgChannel
{
    get
    {
        return _IsPrivMsgChannel;
    }
    set
    {
        _IsPrivMsgChannel = value;
        if (_IsPrivMsgChannel)
        {
            Joined = true;
        }
    }
}

public bool Joined
{ 
    get
    {
        return _Joined;
    }
    set
    {
        _Joined = value;
        // Notify the UI thread!
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Joined"));
    }
}

初始化对象时将设置第一个属性,它不会更改。第二个属性可能会更改,然后会向UI发送通知。

我想基于IsPrivMsgChannel属性更改TabCtem的TabItem模板,并根据Joined属性更改TabContent模板。


更新我的解决方案现在看起来像这样:

<TabControl x:Name="Channels" Grid.Column="0" Grid.Row="1" TabStripPlacement="Left" SelectionChanged="ChannelChanged" ContentTemplateSelector="{StaticResource MyContentTemplateSelector}" ItemTemplateSelector="{StaticResource MyItemTemplateSelector}">
<TabControl.Resources>
    <DataTemplate x:Key="TabItemChannelTemplate">
        <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Name}"></Label>
    </DataTemplate>
    <DataTemplate x:Key="TabItemPrivChatTemplate">
        <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="Private"></Label>
    </DataTemplate>

    <DataTemplate x:Key="TabContentDisconnected">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>

            <Label Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Description}"></Label>
            <Button Grid.Column="0" Grid.Row="1" Width="100" Content="Enter this channel" Click="Enter_Channel"></Button>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="TabContentConnected">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="40"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>

            <Label Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding Description}"></Label>
            <Button Grid.Column="0" Grid.Row="1" Width="100" Content="Leave this channel" Click="Leave_Channel"></Button>
            <DockPanel Grid.Column="0" Grid.Row="2">
                <ListBox x:Name="GameList" HorizontalContentAlignment="Stretch" ItemTemplate="{DynamicResource GameListTemplate}" ItemsSource="{Binding GameList}" Visibility="{Binding CanHost, Converter={StaticResource BoolToVisibilityConverter}}" DockPanel.Dock="Top" Height="250" SelectionChanged="GameListSelectionChanged"></ListBox>
                <ScrollViewer VerticalScrollBarVisibility="Auto" ScrollChanged="MessageScrollChanged" DockPanel.Dock="Bottom">
                    <TextBox x:Name="Messages" Text="{Binding Messages}" TextWrapping="Wrap"></TextBox>
                </ScrollViewer>
            </DockPanel>
        </Grid>
    </DataTemplate>
    <Style TargetType="{x:Type TabItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Joined}" Value="True">
                <Setter Property="ContentTemplate" Value="{StaticResource TabContentConnected}"></Setter>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</TabControl.Resources>
</TabControl>

所以我做了两个DataTemplateSelector类。一个将选择项目的模板,一个将选择内容的模板。

但是由于Joined属性可以更改,我必须创建Style.Triggers来处理该属性是否更改并在需要时更改ContentTemplate。

我唯一无法理解的是为什么触发器只能使用Style的TargetType TabItem,而不能使用TargetType TabControl。

2 个答案:

答案 0 :(得分:1)

听起来我想要使用DataTemplateSelector。这里有一个使用它的例子:http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector

基本上,您实现DataTemplateSelector,其中SelectTemplate方法根据容器和项目选择要使用的模板,在XAML中创建它的实例,然后将其分配给{{1项目控件的属性。

答案 1 :(得分:0)

修改数据触发器,如下所示。

   <DataTrigger Binding="{Binding Path=DataContext.Joined,RelativeSource={RelativeSource Self}}" Value="True">
     <Setter Property="ContentTemplate" Value="{DynamicResource TabContentConnected}" />
   </DataTrigger>
   <DataTrigger Binding="{Binding Path=DataContext.IsPrivMsgChannel,RelativeSource={RelativeSource Self}}" Value="True">
     <Setter Property="ItemTemplate" Value="{DynamicResource TabItemTemplate2}" />
   </DataTrigger>