我在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。
答案 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>