2010-10-13 5 views
1

J'ai un ListBox dans un fichier appelé Downloads.XAML. Les éléments liés à cette ListBox proviennent d'une liste liée dans mon ViewModel. J'ai des états qui sont définis dans le style ListBoxItem dans un contrôle XAML différent qui doit être déclenché en fonction d'une propriété définie sur l'élément lié. Le problème que j'ai est que je ne peux pas obtenir le ListBoxItem du ListBox, car le .SelectedItem fait référence à l'objet lié réel plutôt que le ListBox. J'ai essayé d'utiliser le ListBox.ItemContainerGenerator mais cela ne renvoie qu'un ListItem environ 80% du temps, l'autre 20% du temps cela renvoie null et donc le VisualState n'est pas défini sur le ListBoxItem pertinent.Silverlight obtenir ListBoxItem à partir de la liste des liens

J'ai également essayé de définir les états via les déclencheurs de données dans le XAML, mais encore une fois cela ne fonctionne pas 100% du temps. Est-ce que quelqu'un sait comment je peux facilement obtenir le ListBoxItem de l'objet lié afin de déclencher le VisualState sur ce que j'ai besoin? Les éléments qui sont liés à la liste dans le ListBox sont ajoutés à partir d'une page différente - la page de téléchargements n'est pas visible pour le moment et je pense que c'est pourquoi les ListBoxItems ne sont pas trouvés ou pourquoi les états ne sont pas mis à la porte?

Voici le XAML du modèle de contrôle de ListBoxItem dans le style:

<Style x:Key="PrimaryDownloadsListBoxItemStyle" TargetType="ListBoxItem"> 
    <Setter Property="Padding" Value="3"/> 
    <Setter Property="HorizontalContentAlignment" Value="Left"/> 
    <Setter Property="VerticalContentAlignment" Value="Top"/> 
    <Setter Property="Background" Value="Transparent"/> 
    <Setter Property="BorderThickness" Value="1"/> 
    <Setter Property="TabNavigation" Value="Local"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="ListBoxItem" > 
       <Grid Margin="0" Height="71"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="5"/> 
         <RowDefinition Height="5"/> 
         <RowDefinition Height="52"/> 
         <RowDefinition Height="5"/> 
         <RowDefinition Height="5"/> 
        </Grid.RowDefinitions> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="5"/> 
         <ColumnDefinition Width="90"/> 
         <ColumnDefinition Width="10"/> 
         <ColumnDefinition Width="10"/> 
         <ColumnDefinition Width="184"/> 
         <ColumnDefinition Width="116"/> 
         <ColumnDefinition Width="220"/> 
         <ColumnDefinition Width="67"/> 
         <ColumnDefinition Width="10"/> 
        </Grid.ColumnDefinitions>       
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"/> 
          <VisualState x:Name="MouseOver"/> 
          <VisualState x:Name="Disabled"/> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="SelectionStates"> 
          <VisualState x:Name="Unselected"/> 
          <VisualState x:Name="Selected"> 
           <Storyboard> 
            <ColorAnimation Duration="0" To="#FF191919" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="fillColor2" d:IsOptimized="True"/> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="SelectedUnfocused"/> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="FocusStates"> 
          <VisualState x:Name="Focused"/> 
          <VisualState x:Name="Unfocused"/> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="LayoutStates"> 
          <VisualState x:Name="AfterLoaded"/> 
          <VisualState x:Name="BeforeLoaded"/> 
          <VisualState x:Name="BeforeUnloaded"/> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="DownloadStates"> 
          <VisualState x:Name="DownloadInProgress"> 
... 

Voici le code que je utilise dans le code derrière pour tenter de définir l'état:

 private void SetDownloadState(object[] itemDetails) 
    { 
     DispatcherHelper.CheckBeginInvokeOnUI(() => 
            { 
             var item = itemDetails; 
             if (item != null) 
             { 
              string state = (string)item[0]; 
              VideoItem vi = (VideoItem)item[1]; 

              if (DownloadsListBox.ItemContainerGenerator != null) 
              { 
               DownloadsListBox.ScrollIntoView(DownloadsListBox.Items[0]); 

               foreach (var videoitem in 
                DownloadsListBox.Items.Where(videoitem => videoitem == vi)) 
               { 
                DownloadsListBox.ScrollIntoView(videoitem); 
               } 

               var listBoxItem = DownloadsListBox.ItemContainerGenerator.ContainerFromItem(vi) as ListBoxItem; 

               //show the status state on this item. 
               if (listBoxItem != null) 
               { 
                if (state.ToUpper() == "DOWNLOADING") 
                { 
                 bool success = VisualStateManager.GoToState(listBoxItem, "DownloadInProgress", true); 
                 if (!success) 
                 { 
                  Debug.WriteLine("Error changing state in DownloadsView to Downloading!"); 
                 } 
                } 
                else if (state.ToUpper() == "COMPLETED") 
                { 
                 bool success = VisualStateManager.GoToState(listBoxItem, "DownloadComplete", 
                        true); 
                 if (!success) 
                 { 
                  Debug.WriteLine("Error changing state in DownloadsView to completed!"); 
                 } 
                } 
               } 
               else 
               { 
                Debug.WriteLine("listBoxItem is null"); 
               } 
              } 
             } 
            }); 
    } 

J'ai essayé d'ajouter les triggers dans le ContentTemplate dans le style mais cela n'a pas fonctionné 100% du temps:

     <i:Interaction.Triggers> 
         <ei:DataTrigger Binding="{Binding DownloadState}" Value="Downloading"> 
          <ei:GoToStateAction StateName="Focused"/> 
          <ei:GoToStateAction StateName="DownloadInProgress"/> 
         </ei:DataTrigger> 
         <ei:DataTrigger Binding="{Binding DownloadState}" Value="DownloadComplete"> 
          <ei:GoToStateAction StateName="Focused"/> 
          <ei:GoToStateAction StateName="DownloadComplete"/> 
         </ei:DataTrigger> 
        </i:Interaction.Triggers> 

Répondre

1

Je réussi à mettre la main sur la ListBoxItem en définissant une propriété dans mon modèle en vue de la TemplatedParent de la grille dans le ContentTemplate qui a ensuite fait référence à la ListBoxItem:

"{Binding RelativeSource={RelativeSource TemplatedParent}}" 

Espérons que cela aidera quelqu'un quelque temps :)

Questions connexes