2013-04-25 12 views
8

Próbuję użyć ItemTemplateSelector na listbox w siatce, którą tworzę na innym pliku, aby później zostać wywołanym przez MainWindow.Listbox ItemTemplate Selector nie wybiera szablonu

Oto mój kod DataTemplateSelector

public class TemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     FrameworkElement element = container as FrameworkElement; 
     if (element != null && item != null && item is myClass) 
     { 
      myClass agg = item as myClass; 
      if(agg.myType == a) 
      { 
       return element.FindResource("greenItemTemplate") as DataTemplate; 
      } 
      else if (agg.myType == b) 
      { 
       return element.FindResource("yellowItemTemplate") as DataTemplate; 
      } 
      else if (agg.myType == c) 
      { 
       return element.FindResource("redItemTemplate") as DataTemplate; 
      } 
     } 

     return null; 
    } 
} 

Tu jest mój XAML

<Grid x:Class="NS.Views.ListView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:c="clr-namespace:NS.Commons" 
    DataContext="{Binding}"> 
<Grid.Resources> 
    <c:myConverter x:Key="converter" /> 
    <c:TemplateSelector x:Key="borderSelector" /> 
    <DataTemplate x:Key="greenItemTemplate"> 
     <Border BorderThickness="3" BorderBrush="Green"> 
      <StackPanel HorizontalAlignment="Stretch"> 
       <TextBlock Text="{Binding Path=GroupName}"/> 
       <TextBlock Text="{Binding Path=myType}"/> 
      </StackPanel> 
     </Border> 
    </DataTemplate> 
      <DataTemplate x:Key="redItemTemplate"> 
     <Border BorderThickness="3" BorderBrush="Red"> 
      <StackPanel HorizontalAlignment="Stretch"> 
       <TextBlock Text="{Binding Path=GroupName}"/> 
       <TextBlock Text="{Binding Path=myType}"/> 
      </StackPanel> 
     </Border> 
    </DataTemplate> 
    <DataTemplate x:Key="yellowItemTemplate"> 
     <Border BorderThickness="3" BorderBrush="Yellow"> 
      <StackPanel HorizontalAlignment="Stretch"> 
       <TextBlock Text="{Binding Path=GroupName}"/> 
       <TextBlock Text="{Binding Path=myType}"/> 
      </StackPanel> 
     </Border> 
    </DataTemplate> 
</Grid.Resources> 

<ListBox ItemsSource="{Binding myCollectionOfMyClassObjects}" 
     Name="listBox1" 
     HorizontalContentAlignment="Stretch" 
     ItemTemplateSelector="{StaticResource borderSelector}" 
     > 
</ListBox> 

Jednak mimo wiążących działa dobrze (lista niesformatowany obiektów pojawi się na liście) ItemTemplateSelector nie wywołuje metod TemplateSelector. Wprowadziłem punkt przerwania na początku metod i nigdy nie jest wywoływany.

Czy ktoś wie, jaki może być problem?

+2

BorderBrush swojej granicy Szablony jest zawsze zielony. –

+0

Dzięki za komentarz, chociaż to nie jest problem. Tak właśnie napisałem pytanie, ponieważ nie chciałem opublikować dokładnego kodu. Dzięki jeszcze raz. Pozwól mi to edytować, aby nie rozpraszać. – locorecto

+2

Czy Twój 'ItemsSource' z' ListBox' zmienia się po załadowaniu? Nie sądzę, aby 'TemplateSelectors' reagował na zdarzenia PropertyChanged lub CollectChanged - Są one oceniane tylko raz, gdy program ładuje się – Rachel

Odpowiedz

7

@Rachel ma rację. Twój DataTemplateSelector zostanie wywołany tylko raz przy załadowaniu, a nie dla zmian INPC.

Co można zrobić za to, czego potrzebują, to użyć ListBoxItemStyle z DataTrigger przełączającego Template wykorzystywane

coś takiego:

<ControlTemplate x:Key="greenItemTemplate"> 
    <Border BorderBrush="Green" 
      BorderThickness="3"> 
    <StackPanel HorizontalAlignment="Stretch"> 
     <TextBlock Text="{Binding Path=GroupName}" /> 
     <TextBlock Text="{Binding Path=myType}" /> 
    </StackPanel> 
    </Border> 
</ControlTemplate> 
<ControlTemplate x:Key="redItemTemplate"> 
    <Border BorderBrush="Red" 
      BorderThickness="3"> 
    <StackPanel HorizontalAlignment="Stretch"> 
     <TextBlock Text="{Binding Path=GroupName}" /> 
     <TextBlock Text="{Binding Path=myType}" /> 
    </StackPanel> 
    </Border> 
</ControlTemplate> 
<ControlTemplate x:Key="yellowItemTemplate"> 
    <Border BorderBrush="Yellow" 
      BorderThickness="3"> 
    <StackPanel HorizontalAlignment="Stretch"> 
     <TextBlock Text="{Binding Path=GroupName}" /> 
     <TextBlock Text="{Binding Path=myType}" /> 
    </StackPanel> 
    </Border> 
</ControlTemplate> 
<Style x:Key="MyListBoxItemStyle" 
     TargetType="{x:Type ListBoxItem}"> 
    <Setter Property="Template" 
      Value="{DynamicResource greenItemTemplate}" /> 
    <Style.Triggers> 
    <DataTrigger Binding="{Binding myType}" 
        Value="c"> 
     <Setter Property="Template" 
       Value="{DynamicResource redItemTemplate}" /> 
    </DataTrigger> 
    <DataTrigger Binding="{Binding myType}" 
        Value="b"> 
     <Setter Property="Template" 
       Value="{DynamicResource yellowItemTemplate}" /> 
    </DataTrigger> 
    </Style.Triggers> 
</Style> 

i wykorzystania:

<ListBox ItemContainerStyle="{StaticResource MyListBoxItemStyle}" 
     ItemsSource="{Binding myCollectionOfMyClassObjects}" 
     Name="listBox1" 
     HorizontalContentAlignment="Stretch" /> 
+1

To rozwiązanie działa świetnie. Dzięki za poświęcony czas. – locorecto

+1

Twoje powitanie :) – Viv

+1

@ user971602 Widzę, że nie zaakceptowałeś odpowiedzi. czy jest z tym jakiś problem? Jestem ciekawy – Viv

Powiązane problemy