我正在使用此代码段来分析我在数据网格上选择的行。
for (int i = 0; i < dgDetalle.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dgDetalle.ItemContainerGenerator.ContainerFromIndex(i);
FrameworkElement cellContent = dgDetalle.Columns[0].GetCellContent(row);
// ... code ...
}
循环运行平稳,但在处理某些索引时,第二行会抛出一个空异常。 MSDN的文档说如果'如果项目没有实现',ItemContainerGenerator.ContainerFromIndex(i)
将返回null,但这无助于我猜测我如何获得所需的值。
如何扫描所有行?还有其他办法吗?
更新
我正在使用此代码段阅读CheckBox
here。所以我不能使用绑定或ItemSource
,除非我改变了很多东西。我不能。我正在进行代码维护。
答案 0 :(得分:17)
试试这个,
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
grid.UpdateLayout();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
答案 1 :(得分:7)
DataGrid
正在虚拟化项目,只有当行在视图中时才会创建相应的行(即容器)。
你可以turn off virtualization(如果你有很多项目,第一次加载非常慢,内存使用率也会更高),或者只是迭代数据并检查数据对象的值“应绑定到数据网格的属性。通常你根本不需要UI元素......
答案 2 :(得分:1)
使用此订阅:
TheListBox.ItemContainerGenerator.StatusChanged += (sender, e) =>
{
TheListBox.Dispatcher.Invoke(() =>
{
var TheOne = TheListBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
if (TheOne != null)
// Use The One
});
};
答案 3 :(得分:0)
除了其他答案:控件类的构造函数(页面/窗口/等)中没有项目。
如果要在创建后访问它们,请使用Loaded
事件:
public partial class MyUserControl : UserControl
{
public MyUserControl(int[] values)
{
InitializeComponent();
this.MyItemsControl.ItemsSource = values;
Loaded += (s, e) =>
{
for (int i = 0; i < this.MyItemsControl.Items.Count; ++i)
{
// this.MyItemsControl.ItemContainerGenerator.ContainerFromIndex(i)
}
};
}
}
答案 4 :(得分:0)
在我的情况下,grid.UpdateLayout();
没有帮助,我需要一个DoEvents()
:
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
WPFTools.DoEvents();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
/// <summary>
/// WPF DoEvents
/// Source: https://stackoverflow.com/a/11899439/1574221
/// </summary>
public static void DoEvents()
{
var frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(
delegate (object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}), frame);
Dispatcher.PushFrame(frame);
}