2015-04-16 2 views
0

У меня есть ItemsControl определен нижеContentPresenter не может найти контроль

<ItemsControl Name="PlannerItemControl"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Grid Name="MainGrid"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="200"/> 
       <ColumnDefinition Width="Auto" /> 
       <ColumnDefinition /> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*" /> 
       <RowDefinition Height="auto" /> 
      </Grid.RowDefinitions> 
      <TextBox Name="test" ></TextBox> 
... 
... 
... 
      </Grid> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

В моем коде позади, я хочу, чтобы перебрать все элементы управления в элементе

PlannerItemControl.ItemsSource = Plannermod.TimetableModelList; 

foreach (var item in PlannerItemControl.Items) 
{ 
    ContentPresenter cp = PlannerItemControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter; 
    TextBox tb = FindVisualChild<TextBox>(cp); 
    if (tb != null) 
    { 
       // do something with the textbox 
    } 
} 

public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
{ 
    if (depObj != null) 
    { 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
     if (child != null && child is T) 
     { 
     return (T)child; 
     } 

     T childItem = FindVisualChild<T>(child); 
     if (childItem != null) return childItem; 
    } 
    } 
    return null; 
}  

Проблема заключается в Значение cp всегда равно null, хотя в элементе items есть элементы, так как я попадаю в цикл foreach. Пожалуйста, помогите

+0

Это может быть полезно: http://stackoverflow.com/questions/16184172/itemcontainergenerator -containerfromitem-returns-null-while-virtualizingstackp, http://stackoverflow.com/questions/6713365/itemcontainergenerator-containerfromitem-returns-null. – goobering

+0

Возможно, вы ошибаетесь. Вместо того, чтобы кастинг в ContentPresenter, откройте в FrameworkElement :) или начните поиск прямо из ItemsControl. Нет необходимости в контейнере. Измените FindVisualChild, чтобы искать и сопоставлять DataContext с элементом –

+0

@dev hedgehog проблема возникает перед FindVisualChild. cp имеет значение null. Я попытался изменить бросок на FrameworkElement, но это не помогает. Также попытался передать элемент непосредственно в FindVisualChild (с приложением в качестве зависимого объекта), но это не работает – user2837961

ответ

1

Я думаю, проблема в Xaml, но я не могу понять, что это точно. Может быть, другие стили? Следующий код проверен и работает хорошо

MainWindow XAML:

<ItemsControl x:Name="PlannerItemControl" Width="100" Height="100"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Grid x:Name="MainGrid"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="200"/> 
         <ColumnDefinition Width="Auto" /> 
         <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="*" /> 
         <RowDefinition Height="auto" /> 
        </Grid.RowDefinitions> 
        <TextBox x:Name="test" ></TextBox> 

       </Grid> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
    <Button Height="20" Width="100" Click="ButtonBase_OnClick"> Click me!</Button> 
      </StackPanel> 

MainWindow.cs:

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new MainViewModel(); 
      PlannerItemControl.ItemsSource = new List<string>() {"a", "b", "c"}; 

     } 



     public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject 
     { 
      if (depObj != null) 
      { 
       for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
       { 
        DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
        if (child != null && child is T) 
        { 
         return (T)child; 
        } 

        T childItem = FindVisualChild<T>(child); 
        if (childItem != null) return childItem; 
       } 
      } 
      return null; 
     }  

     private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
     { 
      foreach (var item in PlannerItemControl.Items) 
      { 
       ContentPresenter cp = PlannerItemControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter; 
       TextBox tb = FindVisualChild<TextBox>(cp); 
       if (tb != null) 
       { 
        tb.Text = item.ToString(); 
        // do something with the textbox 
       } 
      } 
     } 
    } 
+0

Спасибо @Dragosh Stoica. Я думаю, что положить его в кнопку сделал трюк, когда элементы управления отображаются точно – user2837961

+0

Рад слышать, что вам удалось найти способ сделать это! –

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