2010-02-27 5 views
3

J'ai une application Silverlight qui utilise un DataGrid. A l'intérieur de cette DataGrid J'ai un DataTemplate qui est défini comme suit:Silverlight - Obtient le ItemsControl d'un DataTemplate

<Grid x:Name="myGrid" Tag="{Binding}" Loaded="myGrid_Loaded"> 
    <ItemsControl ItemsSource="{Binding MyItems}" Tag="{Binding}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel Orientation="Horizontal" Width="138"> 
      <TextBlock Text="{Binding Type}" /> 
      <TextBox x:Name="myTextBox" TextChanged="myTextBox_TextChanged" /> 
      </StackPanel> 
     </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</Grid> 

Lorsqu'un utilisateur saisit du texte dans la zone de texte, j'ai un événement (myTextBox_TextChanged) qui doit être tiré à ce moment. Lorsque cet événement est déclenché, je voudrais obtenir l'élément ItemsControl qui est le conteneur pour ce TextBox. Comment puis-je obtenir ItemsControl à partir de mon gestionnaire d'événements?

Veuillez noter: Étant donné que ItemsControl est dans le DataTemplate de DataGrid, je ne crois pas que je puisse simplement ajouter un x: Name et le référencer à partir de mon code-behind. Ou y a-t-il un moyen de le faire?

Merci!

+0

Pouvez-vous me dire pourquoi vous avez besoin d'une référence à ItemsControl? Je pense qu'il y a peut-être une meilleure solution globale cachée ici. – bendewey

Répondre

4

En utilisant une combinaison de ItemsControl.ItemsControlFromItemContainer et VisualTreeHelper.GetParent vous devriez pouvoir trouver votre ItemsControl

var txt = sender as TextBox; 
var panel1 = VisualTreeHelper.GetParent(txt); 
var panel2 = VisualTreeHelper.GetParent(panel1); 
var contentPresenter = VisualTreeHelper.GetParent(panel2); 
var ic = ItemsControl.ItemsControlFromItemContainer(contentPresenter); 

Vous pouvez également rechercher sur le web pour les fonctions récursives VisualTreeHelper pour faire partie de ce plus facile.

4

J'aime avoir cette petite méthode d'extension dans une classe statique quelque part dans mon application: -

public static IEnumerable<DependencyObject> Ancestors(this DependencyObject root) 
{ 
    DependencyObject current = VisualTreeHelper.GetParent(root); 
    while (current != null) 
    { 
     yield return current; 
     current = VisualTreeHelper.GetParent(current); 
    } 
} 

Avec que vous devriez être en mesure de faire quelque chose comme ceci: -

ItemsControl control = ((DependencyObject)sender).Ancestors() 
    .TypeOf<ItemsControl>().FirstOrDefault(); 
+0

Est tombé sur cela après des tonnes de recherche autour. J'essayais de comprendre comment mettre à jour un deuxième ComboBox dans une rangée quand le premier index de ComboBox a changé. Cela me facilitera la tâche de trouver le parent DataGridRow et par la suite le deuxième ComboBox dans la même ligne. Merci! – Chris

0

Non Assurez-vous que cela s'applique, mais cela crée une "barre de boutons à bascule" en utilisant les mêmes principes.

private void UIClassButton_Click(object sender, RoutedEventArgs e){ 
Button SenderButton = (Button)sender; 
ItemsControl SendersItemControl = ItemsControl.ItemsControlFromItemContainer(VisualTreeHelper.GetParent(SenderButton)); 
IEnumerable<DependencyObject> DependencyObjectCollection = SendersItemControl.GetContainers(); 

foreach (ContentPresenter item in DependencyObjectCollection) { 
    ContentPresenter UIClassPresenter = (ContentPresenter)item; 
    Button UIClassButton = (Button)UIClassPresenter.GetVisualChildren().First(); 
    if (UIClassButton != SenderButton) { 
     VisualStateManager.GoToState(UIClassButton, "Normal", true); 
    } 
    else { 
     VisualStateManager.GoToState(UIClassButton, "Pressed", true); 
    } 
} 
} 
0

Voici un exemple de capturer un conteneur qui héberge votre pièce de ItemsControl:

 CheckBox checkbox = sender as CheckBox; 

     foreach (var item in MembersItemsControl.Items) 
     { 
      var container = MembersItemsControl.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; 

      UserInformation user = container.DataContext as UserInformation; 

      bool isMale = true; 
      if (user.sex == isMale && checkbox.IsChecked.Value == true) 
      { 
       container.Visibility = System.Windows.Visibility.Visible; 
      } 
     } 

J'espère que cela aide.

Questions connexes