2010-02-27 3 views
3

У меня есть приложение Silverlight, которое использует DataGrid. Внутри этого DataGrid У меня есть DataTemplate, который определен как следующий:Silverlight - Get ItemsControl 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> 

Когда пользователь вводит текст в TextBox, у меня есть событие (myTextBox_TextChanged), которые должны быть запущены в данный момент. Когда это событие будет запущено, я хотел бы получить элемент ItemsControl, который является контейнером для этого TextBox. Как получить этот элемент ItemsControl из моего обработчика событий?

Обратите внимание: поскольку элемент ItemsControl находится в DataTemplate DataGrid, я не верю, что могу просто добавить x: Name и ссылаться на него с моего кода. Или есть способ сделать это?

Спасибо!

+0

Можете ли вы рассказать мне, почему вам нужна ссылка на элемент ItemsControl, который я чувствую, может быть лучшее общее решение, скрытое здесь. – bendewey

ответ

4

Используя комбинацию ItemsControl.ItemsControlFromItemContainer и VisualTreeHelper.GetParent вы должны быть в состоянии найти свой 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); 

Вы также можете искать в Интернете функции VisualTreeHelper рекурсивные, чтобы сделать некоторые из этого легче.

4

Я хотел бы иметь этот маленький метод расширения в статическом классе где-то в моем приложении: -

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

При том, что вы должны быть в состоянии сделать что-то вроде этого: -

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

Наткнулся на это после тонны поиска. Я пытался выяснить, как обновить второй ComboBox в строке, когда изменился первый индекс ComboBox. Это облегчит мне поиск родительского DataGridRow, а затем второго ComboBox в той же строке. Благодаря! – Chris

0

Не если это применимо, но это создает «панель кнопок переключения» с использованием тех же принципов.

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

Вот пример захвата контейнера, где находится элемент вашего 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; 
      } 
     } 

Я надеюсь, что помогает.

Смежные вопросы