2013-12-21 1 views
0

У меня есть элемент TabControl в WPF .Net с 2 шаблонами для контента и 2 шаблонами для табитов. Я связываю свои собственные объекты, как ItemsSource, который имеет два свойства:Изменение шаблона TabItem и TabContent на основе значений свойств

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

Первое свойство устанавливается при инициализации объекта, оно не изменится. Второе свойство может измениться и затем отправляет уведомление в пользовательский интерфейс.

Я хотел бы изменить шаблон TabItem моего TabContol на основе свойства IsPrivMsgChannel и шаблона TabContent на основе свойства, указанного в объявлении.


UPDATE Мое решение выглядит это прямо сейчас:

<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. Один из них выберет шаблон для элементов, а один выберет шаблон для Контента.

Но так как свойство Own может измениться, я должен создать Style.Triggers для обработки, если это свойство изменится и изменит ContentTemplate, если это необходимо.

Единственное, что я не могу понять, это то, почему триггеры работают только с талисманом TargetType Style, а не с TargetType TabControl.

ответ

1

Звучит так, как будто вы хотите использовать DataTemplateSelector. Там пример его использования здесь: http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector

В принципе, вы реализовать DataTemplateSelector где метод SelectTemplate выбирает, какой шаблон для использования на основе контейнера и данного пункта, создать экземпляр этого в вашем XAML затем присвоить его ItemTemplateSelector атрибут элемента управления элемента.

+0

Спасибо, это первая часть моего решения наверняка, но так как свойство Own может быть изменено Мне нужно как-то обновить ContentTemplate. Я сделал это с помощью Style.Triggers, но я не знаю, почему он работает, только если TargetType моего стиля - TabItem. Вы знаете, почему он не работает с TargetType TabControl? – user2042930

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>