C# ItemsControl.ItemContainerGenerator.ContainerFromItem()是否返回null?

C# ItemsControl.ItemContainerGenerator.ContainerFromItem()是否返回null?,c#,wpf,xaml,C#,Wpf,Xaml,我有一点奇怪的行为,我似乎无法解决。当我遍历ItemsControl.ItemsSource属性中的项时,似乎无法获取容器?我希望看到一个按钮返回,但我只得到null 有什么想法吗 <!-- MyWindow.xaml --> <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.

我有一点奇怪的行为,我似乎无法解决。当我遍历ItemsControl.ItemsSource属性中的项时,似乎无法获取容器?我希望看到一个按钮返回,但我只得到null

有什么想法吗

<!-- MyWindow.xaml -->
    <Window 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1" Height="300" Width="300" Foreground="White" Name="mainPanel">

        <ItemsControl x:Name="ItemsControl_1" Margin="20">
        <!-- ItemsPanelTemplate -->
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="2" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <!-- ItemTemplate -->
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding Path=Prop_1}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    </Window>

我的代码不起作用。返回空值

    public static void StartWindow()
            {

                // MyWindow
                System.Windows.Window win;
                // Load MyWindow
                using (FileStream fs = new FileStream(@"C:\MyWindow.xaml", FileMode.Open))
                {
                    object obj = System.Windows.Markup.XamlReader.Load(fs);
                    win = (System.Windows.Window)obj;
                }

                //This code set ItemsSource
                foreach (DependencyObject fe in FindLogicalChildren<DependencyObject>(win))
                {
                    ItemsControl itemscontrol = fe as ItemsControl;
                    if (fe is ItemsControl)
                    {
                        itemscontrol.ItemsSource = new List<My_Class>() { 
                            new My_Class("Button1"), 
                            new My_Class("Button2"), 
                            new My_Class("Button3") };

                    }
                }
         // This  code get ItemsSource<DependencyObject>
                foreach (DependencyObject fe in FindLogicalChildren<DependencyObject>(win))
                {

                    if (fe is ItemsControl)
                    {
                        ItemsControl itemsControl = fe as ItemsControl;
                        itemsControl.UpdateLayout();
                        for (int i = 0; i < itemsControl.Items.Count; i++)
                        {
                            DependencyObject c = (DependencyObject)itemsControl.ItemContainerGenerator.ContainerFromIndex(i);
                            **//This code return NULL !!!**
                            if (c != null)
                                Display.MsgBox(c.GetType().Name);
                            else
                                Display.MsgBox("NULL");
                        }
                    }
                }
                win.ShowDialog();

            }


public class My_Class
{
    public string Prop_1 { get; set; }

    public My_Class(string prop1)
    {
        Prop_1 = prop1;
    }
}

            public static IEnumerable<T> FindLogicalChildren<T>(DependencyObject depObj) where T : DependencyObject
            {
                if (depObj != null)
                {
                    foreach (object rawChild in LogicalTreeHelper.GetChildren(depObj))
                    {
                        if (rawChild is DependencyObject)
                        {
                            DependencyObject child = (DependencyObject)rawChild;
                            if (child is T)
                            {
                                yield return (T)child;
                            }

                            foreach (T childOfChild in FindLogicalChildren<T>(child))
                            {
                                yield return childOfChild;
                            }
                        }
                    }
                }
            }
public static void StartWindow()
{
//我的窗口
System.Windows.windowwin;
//加载我的窗口
使用(FileStream fs=newfilestream(@“C:\MyWindow.xaml”,FileMode.Open))
{
objectobj=System.Windows.Markup.XamlReader.Load(fs);
win=(System.Windows.Window)obj;
}
//此代码集为ItemsSource
foreach(FindLogicalChildren(win)中的DependencyObject fe)
{
ItemsControl ItemsControl=fe作为ItemsControl;
如果(fe是ItemsControl)
{
itemscontrol.ItemsSource=新列表(){
新My_类(“按钮1”),
新My_类(“按钮2”),
新My_类(“按钮3”)};
}
}
//此代码获取ItemsSource
foreach(FindLogicalChildren(win)中的DependencyObject fe)
{
如果(fe是ItemsControl)
{
ItemsControl ItemsControl=fe作为ItemsControl;
itemsControl.UpdateLayout();
对于(int i=0;i
窗口已加载


ContainerFromIndex方法将返回ContentPresenter。您可以获得如下按钮的引用:

ItemsControl itemsControl = ItemsControl_1;
for (int i = 0; i<itemsControl.Items.Count; i++)
{
    ContentPresenter cp = itemsControl.ItemContainerGenerator.ContainerFromIndex(i) as ContentPresenter;
    if (cp != null && VisualTreeHelper.GetChildrenCount(cp) > 0)
    {
        Button button = VisualTreeHelper.GetChild(cp, 0) as Button;
        //...
    }
}

ContentPresenter
是一个
DependencyObject
,因此他可能无法得到他所期望的(
按钮
),但它不能解释
null
值。我想这样更好:)win.Loaded+=(ss,ee)=>谢谢,这解决了我的问题。太好了。请记住接受答案并投票表决:作为旁注,如果您在集合更新后立即访问这些项目,则视觉元素可能尚未加载,您将无法访问它们。itemsControl.UpdateLayout()为我修复了此问题。您确定在尝试访问项目之前已加载窗口和itemsControl吗?检查
itemsControl.IsLoaded
属性,如果未加载代码,请重新设计代码。
public static void StartWindow()
{
    // MyWindow
    System.Windows.Window win;
    // Load MyWindow
    using (FileStream fs = new FileStream(@"C:\MyWindow.xaml", FileMode.Open))
    {
        object obj = System.Windows.Markup.XamlReader.Load(fs);
        win = (System.Windows.Window)obj;
    }

    win.Loaded += (ss, ee) => 
    {
        //access the containers here...
    };

    win.ShowDialog();
}