C# ItemsControl.ItemContainerGenerator.ContainerFromItem()是否返回null?
我有一点奇怪的行为,我似乎无法解决。当我遍历ItemsControl.ItemsSource属性中的项时,似乎无法获取容器?我希望看到一个按钮返回,但我只得到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.
<!-- 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();
}