2011-06-06 38 views
0

我試圖在切換ListBoxItem的ContentPresenter時選中它,同時使用多個DataTemplates來表示不同類型的數據。根據選擇切換ListBoxItem的ContentPresenter

這裏是限定內部列表框的用戶控件:要顯示

<UserControl x:Class="Homage.View.FilePanelView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:vw="clr-namespace:Homage.View" 
     xmlns:vm="clr-namespace:Homage.ViewModel" 
     xmlns:ctrl="clr-namespace:Homage.Controls" 
     mc:Ignorable="d"> 

<UserControl.Resources> 
    <DataTemplate DataType="{x:Type vm:SlugViewModel}"> 
     <vw:SlugView /> 
    </DataTemplate> 

    <DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> 
     <vw:HeaderSlugView /> 
    </DataTemplate> 

    <DataTemplate DataType="{x:Type vm:ContentSlugViewModel}"> 
     <vw:ContentSlugView /> 
    </DataTemplate> 

    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
        <Border Name="SlugContainer" Background="Transparent" BorderBrush="Black" BorderThickness="1" CornerRadius="2" Margin="0,5,0,0" Padding="5"> 
         <Grid> 
          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto" /> 
           <RowDefinition Height="*" /> 
          </Grid.RowDefinitions> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="*" /> 
          </Grid.ColumnDefinitions> 

          <Label Grid.Row="0" Content="{Binding DisplayName}" /> 
          <ContentPresenter Grid.Row="1" /> 

         </Grid> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter TargetName="SlugContainer" Property="BorderThickness" Value="5" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</UserControl.Resources> 

<Grid> 
    <ListBox ItemsSource="{Binding Slugs}" Padding="5" /> 
</Grid> 
</UserControl> 

基於數據的類型(例如,「頁眉彈頭」)在一定的DataTemplate被施加到ListBoxItem的。這很好,但我希望將所選ListBoxItem的DataTemplate調整爲不同的DataTemplate - 同樣,基於顯示的數據類型。

目標是,由於每種數據類型都不相同,因此每個數據類型在未選中時都會具有唯一的外觀,並且在選定時會收到一組唯一的選項。

如果我能得到上面的工作,那將是偉大的!但是,我也想讓事情變得複雜......

儘管每種數據類型都有獨特的控件,但它們也具有通用控件。所以我想最好定義所有的常用控件,以便它們出現在ListBox中的相同位置。

<DataTemplate x:Key="CommonSelectedTemplate"> 
    <!-- common controls --> 
    ... 
    <DataTemplate x:Key="UniqueSelectedTemplate"> 
     <!-- all the unique controls --> 
     <ContentPresenter /> 
    </DataTemplate> 
    <!-- more common controls --> 
    ... 
</DataTemplate> 

如果我必須多次定義所有常見的東西(現在),我會活下去。 =)

感謝您的幫助!

+0

[這個答案](http://stackoverflow.com/questions/5759390/wpf-listbox-templating-how-to-create-a-common-template-but-still-change-content/5759656#5759656)可能有幫助與你的第二個問題。 – 2011-06-06 03:44:17

+0

感謝指針H.B.我目前的設置實際上讓我有一個「共同」和「獨特」的部分,但我試圖讓它繼續適用於第一個問題的解決方案。我已經看到了一些基於IsSelected設置外觀的例子,但是目前爲止似乎沒有提供常見和獨特元素的嵌套結構。 – 2011-06-06 16:12:37

+0

您可以使用DataTemplateSelector類。但在這種情況下,您應該將IsSelected屬性添加到每個項目類,並將鍵添加到所有隱式數據模板。關於常用控件,可以用UserControl替換它。 – vorrtex 2011-09-26 19:08:10

回答

0

假設我們只有兩種數據類型:Item1ViewModelItem2ViewModel。因此我們需要4個數據模板:2個用於公共狀態,2個用於選定狀態。

<DataTemplate x:Key="Template1" DataType="local:Item1ViewModel"> 
     <TextBlock Text="{Binding Property1}" Foreground="Red" /> 
    </DataTemplate> 
    <DataTemplate x:Key="Template2" DataType="local:Item2ViewModel"> 
     <TextBlock Text="{Binding Property2}" Foreground="Blue" /> 
    </DataTemplate> 
    <DataTemplate x:Key="Template1Selected" DataType="local:Item1ViewModel"> 
     <TextBlock Text="{Binding Property1}" Background="Yellow" Foreground="Red" /> 
    </DataTemplate> 
    <DataTemplate x:Key="Template2Selected" DataType="local:Item2ViewModel"> 
     <TextBlock Text="{Binding Property2}" Background="Yellow" Foreground="Blue" /> 
    </DataTemplate> 

對於基於不同類型的切換兩個模板之間的內容我使用DataTemplateSelector類:

public class SampleTemplateSelector:DataTemplateSelector 
{ 
    public DataTemplate Type1Template { get; set; } 
    public DataTemplate Type2Template { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item is Item1ViewModel) 
      return Type1Template; 
     else if (item is Item2ViewModel) 
      return Type2Template; 

     return null; 
    } 
} 

我們需要這種選擇的兩個實例:一個是共同的狀態和一個用於選擇狀態。

<local:SampleTemplateSelector x:Key="templateSelector" 
            Type1Template="{StaticResource Template1}" 
            Type2Template="{StaticResource Template2}"/> 
    <local:SampleTemplateSelector x:Key="selectedTemplateSelector" 
            Type1Template="{StaticResource Template1Selected}" 
            Type2Template="{StaticResource Template2Selected}"/> 

之後,你應該加入這樣的代碼,其切換兩個選擇:

<DataTemplate x:Key="ListItemTemplate"> 
     <ContentControl x:Name="content" Content="{Binding}" ContentTemplateSelector="{StaticResource templateSelector}" /> 
     <DataTemplate.Triggers> 
      <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" Value="True"> 
       <Setter TargetName="content" Property="ContentTemplateSelector" Value="{StaticResource selectedTemplateSelector}"/> 
      </DataTrigger> 
     </DataTemplate.Triggers> 
    </DataTemplate> 

這一切,將此ItemTemplateListBox不改變ControlTemplate

<ListBox ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ListItemTemplate}" />