2015-04-16 61 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; 
}  

問題是在因爲我進入了foreach循環,所以cp的值始終爲null,儘管itemscontrol中有項目。請幫助

+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爲空。我試圖改變演員到FrameworkElement,但沒有幫助。還嘗試將項目直接傳遞給FindVisualChild(使用cast作爲dependencyobject),但這不起作用 – user2837961

回答

1

我認爲問題出在Xaml上,但我無法弄清楚什麼是肯定的。也許其他風格?下面的代碼進行測試並運行良好

主窗口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

很高興聽到您設法找到辦法! –