0

J'ai un UserControl personnalisé qui se compose d'un ListBox avec un DataTemplate. Le ListBox obtient sa source définie dans XAML et les éléments dans le DataTemplate obtiennent ses valeurs de Binding.Lier un élément dans un ItemTemplate à une valeur en dehors du ItemSource dans Windows Phone 7

Mon UserControl XAML ressemble à ceci:

<UserControl x:Class="Test.UserControls.TracksListBox" 
    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:converters="clr-namespace:Test.Converters" 
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit" 
    mc:Ignorable="d" 
    d:DesignHeight="480" d:DesignWidth="480" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    Name="this"> 

<UserControl.Resources> 
    <converters:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/> 
</UserControl.Resources> 

<Grid x:Name="LayoutRoot" Background="transparent"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="auto"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <CheckBox Grid.Row="0" IsChecked="{Binding Show}"/> 
    <ListBox Grid.Row="1" Name="List"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel VerticalAlignment="Top" 
          Margin="0 5 0 5"> 
        <TextBlock Text="{Binding Title}"/> 
        <CheckBox IsChecked="{Binding ElementName=this, Path=Show}"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

Et le code-behind:

namespace Test.UserControls 
{ 
    public partial class TracksListBox : UserControl 
    { 
     public static readonly DependencyProperty TracksListProperty = 
      DependencyProperty.Register("TracksList", 
      typeof(List<Track>), 
      typeof(TracksListBox), 
      new PropertyMetadata(null, OnTracksListChanged)); 

     public static readonly DependencyProperty ShowProperty = 
      DependencyProperty.Register("Show", 
      typeof(bool), 
      typeof(TracksListBox), 
      new PropertyMetadata(false)); 

     public TracksListBox() 
     { 
      InitializeComponent(); 
     } 

     public List<Track> TracksList 
     { 
      get 
      { 
       return (List<Track>)GetValue(TracksListProperty); 
      } 
      set 
      { 
       SetValue(TracksListProperty, value); 
      } 
     } 

     public bool Show 
     { 
      get 
      { 
       return (bool)GetValue(ShowProperty); 
      } 
      set 
      { 
       SetValue(ShowProperty, value); 
      } 
     } 

     private static void OnTracksListChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
     { 
      (obj as TracksListBox).OnTracksListChanged((List<Track>)args.OldValue, (List<Track>)args.NewValue); 
     } 

     protected virtual void OnTracksListChanged(List<Track> oldValue, List<Track> newValue) 
     { 
      List.ItemsSource = newValue; 
     } 
    } 
} 

Dans mon MainPage.xaml Je l'utilise comme ceci:

<userControls:TracksListBox x:Name="TopTracksListBox" 
       TracksList="{Binding ElementName=this, Path=TopTracks}" 
       Show="True"/> 

Mon problème est ici au CheckBox à l'intérieur du ListBoxDataTemplate ne sera pas la valeur de Show. L'autre CheckBox dans Grid.Row="0" cependant, obtient la valeur correcte ... Comment lier une valeur de mon UserControl à l'intérieur du DataTemplate du ListBox?

Répondre

0

Cela doit être un bogue, pas plus que ce que j'ai essayé le DataContext de la CheckBox a toujours été nulle ou une Piste. Si vous voulez travailler autour d'elle, vous pouvez ajouter jusqu'à ce que ce sera corrigé

<ListBox.ItemTemplate> 
    <DataTemplate> 
     <StackPanel VerticalAlignment="Top" 
       Margin="0 5 0 5"> 
      <TextBlock Text="{Binding Title}"/> 
      <CheckBox Loaded="CheckBox_Loaded"/> 
     </StackPanel> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

puis définissez la liaison dans le code derrière une fois qu'il est chargé

private void CheckBox_Loaded(object sender, RoutedEventArgs e) 
{ 
    CheckBox checkBox = sender as CheckBox; 
    Binding isCheckedBinding = new Binding("Show"); 
    isCheckedBinding.Source = this; 
    checkBox.SetBinding(CheckBox.IsCheckedProperty, isCheckedBinding); 
} 
+0

Cela a fonctionné comme un charme! Merci :) – greve

0

j'ai laissé tomber votre code dans un contrôle utilisateur dans une application, changé Track à string et ne liait rien à la liste, mais je voyais toujours une case à cocher affichée et la liaison de Show au IsChecked a fonctionné pour moi.

+0

C'est exact. Comme je l'ai dit, la case au-dessus de la ListBox obtient la valeur correcte de Show, mais quand je lie une liste à ListBox, la case à cocher dans chaque élément de la liste n'obtient pas la valeur correcte ... – greve