2012-04-16 70 views
1

我想從一個DataTemplate讓我的切換按鈕爲什麼VisualTreeHelper.GetChildrenCount(lbi)== 0?

ListBoxItem lbi = this.UnitsListBox.ItemContainerGenerator.ContainerFromItem(obj) as ListBoxItem; 

LBI是確定(不爲空)。

我想做到這一點:

ContentPresenter cp = VisualTreeHelper.GetChild(lbi, 0) as ContentPresenter; 
ToggleButton btn = (ToggleButton) VisualTreeHelper.GetChild(cp, 0); 

VisualTreeHelper.GetChildrenCount(lbi) is 0. 

這是我的XAML

<ListBox MaxWidth="215" FlowDirection="RightToLeft" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" DockPanel.Dock="Left" Name="UnitsListBox" VirtualizingStackPanel.IsVirtualizing="False" SelectionChanged="UnitsListBox_SelectionChanged" IsSynchronizedWithCurrentItem="True"> 
       <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel /> 
        </ItemsPanelTemplate> 
       </ListBox.ItemsPanel> 
       <ListBox.Resources> 
        <Style TargetType="Button"/> 
       </ListBox.Resources> 
       <ListBox.ItemTemplate > 
        <DataTemplate > 
         <ToggleButton x:Name="UnitSidebarButton" FlowDirection="LeftToRight" Height="60" Width="60" HorizontalContentAlignment="Center" Background="Transparent" Margin="0" Padding="0" Checked="UnitSidebarButton_Checked" Unchecked="UnitSidebarButton_Unchecked" Focusable="False" VirtualizingStackPanel.IsVirtualizing="False"> 
          <Grid> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="*"/> 
           </Grid.ColumnDefinitions> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="*"/> 
           </Grid.RowDefinitions> 
           <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Converter={StaticResource cIMSidebarConverter2}}" TextWrapping="Wrap" TextAlignment="Center" Background="Transparent"/> 
          </Grid> 
         </ToggleButton> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
+0

您是否確定在運行代碼之前生成了容器? – Rachel 2012-04-16 14:59:48

+0

@Rachel我認爲它們是保證生成的,因爲lbi不爲空。 – 0x4f3759df 2012-04-16 15:01:33

回答

1

當我複製/粘貼你的代碼到測試項目中, ListBoxItem下的可視樹層次結構中的下一項是Border元素,而不是ContentPresenter(我用Snoop查看可視化樹)。我懷疑這就是爲什麼你的ContentPresenter對象爲空。

如果你有興趣,我的博客上有一些VisualTreeHelpers,這可能會使這更容易。您可以使用它們像這樣:

你的容器可能不會產生

var toggleBtn = VisualTreeHelpers.FindChild<ToggleButton>(lbi); 

老回答)這裏有一個如何使用StatusChanged事件,以確定是否一個例子在運行您的代碼之前已經生成或未生成容器

public Window() 
{ 
    InitializeComponent(); 

    // Attach StatusChanged event 
    UnitsListBox.ItemContainerGenerator.StatusChanged += 
     ItemContainerGenerator_StatusChanged; 
} 

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e) 
{ 
    // If containers have been generated 
    if (UnitsListBox.ItemContainerGenerator.Status == 
     System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
    { 
     // Remove event 
     UnitsListBox.ItemContainerGenerator.StatusChanged -= 
      ItemContainerGenerator_StatusChanged; 

     // Do whatever here 
     var lbi = UnitsListBox.ItemContainerGenerator.ContainerFromItem(obj) as ListBoxItem; 

    } 
} 
+0

我用你的代碼,我的容器生成了。它沒有解決問題。 VisualTreeHelper.GetChild(lbi,0)作爲ContentPresenter == null(仍然)。 – 0x4f3759df 2012-04-16 20:22:57

+0

@iterationx在這種情況下,我在猜測'ListBoxItem'下面的控件不是'ContentPresenter'。我將你的代碼複製/粘貼到一個文本項目中,並查看輸出結果,並且它看起來像層次結構中的下一個項目是「Border」,而不是「ContentPresenter」。如果你有興趣,我在我的博客上有一些[helper classes](http://rachel53461.wordpress.com/2011/10/09/navigating-wpfs-visual-tree/),它們在Visual Tree中搜索特定對象更容易。 – Rachel 2012-04-17 12:05:55