2012-04-16 20 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