我试着像这样排:
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
TextBlock cellContent = dataGrid.Columns[0].GetCellContent(row) as TextBlock;
但我只得到null
。还有其他解决方案吗?我做错了什么?
我想从我的手机中获取数据。我的单元格是复选框。
答案 0 :(得分:2)
这取决于您尝试获取此数据的方式/时间。 WPF更适合通过ItemsSource中绑定的对象访问数据。因此,如果您的ItemsSource是MyObject的List,那么特定的行将是MyObject类型而不是纯DataRow。
如果您通过点击来访问数据,则可以执行以下操作:
var currentItem = myDataGrid.SelectedItem as MyObject;
现在,您拥有当前MyObject的最初预期形式,而不是在网格中挑选。
答案 1 :(得分:1)
DataGrid
来处理合适的数据对象以进行操作:由于 DataGrid
对绑定到数据对象的主体进行操作,因此您需要在 DataTable
之类的东西中跟踪您的数据。
例如,为您的 MainWindow 类初始化一个 DataTable 类型的字段并将其命名为相关内容:
public partial class MainWindow : Window
{
private DataTable _cars = new DataTable("Cars");
然后在您的构造函数中,在您初始化 Window 组件之后,将 DataGrid.ItemSource
作为数据视图绑定到 DataTable 的集合:
public MainWindow()
{
InitializeComponent();
dgCars.ItemsSource = _cars.AsDataView();
}
现在,每当您以编程方式向 _cars
表中添加新行时,它们都会反映在 DataGrid
中,是的!但是,您希望能够从用户界面对数据进行操作,所以让我们深入研究吧!
DataTable
中的数据进行操作:当你想对数据进行操作时,你可以从DataGrid
里面的item中获取到什么,并使用它们提供的索引从DataTable
中移除item,然后重新-应用数据视图。这是总结,但我会更详细地完成示例:
我们需要遍历每个 DataGrid
项目并在执行我们的逻辑之前检查它是否被选中:
for (int i = 0; i < dgCars.Items.Count; i++)
{
if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
{
// This is where we do the magic
}
}
但是,我们无法从当前用于提供 DataTable
的 DataGrid
中删除项目,否则我们将遇到 IndexOutOfBounds(以及可能的 Enumeration)错误,因此安全起见,我们将使用表的副本进行操作:
DataTable result = _cars.Copy(); //New in this step
for (int i = 0; i < dgCars.Items.Count; i++)
{
if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
{
result.Rows.RemoveAt(i); //New in this step
}
}
再一次,我们会遇到 IndexOutOfBounds 错误,因为我们对数据进行迭代,就好像有 X
的数据量一样,但是每次我们 RemoveAt(i),我们现在都在迭代超过 X--
的数据量。所以,让我们添加一个计数并跟踪:
int removed = 0; //New in this step
DataTable result = _cars.Copy();
for (int i = 0; i < dgCars.Items.Count; i++)
{
if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
{
//Subtracting `removed` new in this step
result.Rows.RemoveAt(i - removed);
removed++; //New in this step
}
}
最后但并非最不重要的一点是,我们会将 _cars
变量指向堆上的 result
DataTable 对象,然后重新分配 dgCars.ItemSource = _cars.AsDataView()
以更新我们的 DataGrid (如果有兴趣,可以在我回答的最底部对此进行更复杂的解释):
int removed = 0;
DataTable result = _cars.Copy();
for (int i = 0; i < dgCars.Items.Count; i++)
{
if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
{
result.Rows.RemoveAt(i - removed);
removed++;
}
}
_cars = result; //New in this step
dgCars.ItemSource = _cars.AsDataView(); //New in this step
DataGrid
上的行,然后单击 Click
值等于 btnRemove_Click
的按钮来从 DataTable
中删除数据。简单的修改和逻辑改变将允许你做同样的添加、编辑等数据,但按照我们最初开始的原则,即对数据对象(在这种情况下,一个ItemsSource
)和将该项目设为 DataGrid
的 public partial class MainWindow : Window
{
private DataTable _cars = new DataTable("Cars");
public MainWindow()
{
InitializeComponent();
// THIS WASN'T IN THE BUILD EXAMPLE, BUT AS A BONUS:
// We could ALSO use this opportunity to setup static
// column headers if we know what they are in advance!
_cars.Columns.Add("Year");
_cars.Columns.Add("Make");
_cars.Columns.Add("Model");
dgCars.ItemsSource = _cars.AsDataView();
}
private btnRemove_Click(object sender, RoutedEventArgs e)
{
int removed = 0;
DataTable result = _cars.Copy();
for (int i = 0; i < dgCars.Items.Count; i++)
{
if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
{
result.Rows.RemoveAt(i - removed);
removed++;
}
}
_cars = result;
dgCars.ItemSource = _cars.AsDataView();
}
}
。_cars
在前面的第 4 步中,我提到:
<块引用>最后但并非最不重要的是,我们将 result
变量指向我们的 dgCars.ItemSource = _cars.AsDataView()
堆上的 DataTable 对象,然后重新分配 _cars
以更新我们的 DataGrid
这是因为result
和_cars
都是从类实例化的对象,所以它们驻留在堆上。当堆栈上不再有对它们的引用时,堆上的项目被垃圾收集(从内存中删除)。由于 MainWindow
是我们的 btnRemove_Click
的一个字段,并且在 DataTable result
的范围之外继续,当我们将它指向 btnRemove_Click
时,我们保留对该表的引用,并删除我们参考了原表。因此,当 result
完成时,变量 DataTable
被垃圾回收,_cars
用来指向的旧 _cars
被垃圾回收,trt <- rep(LETTERS[1:3],3)
qw <- sample(100,9)
tr <- sample(100,9)
df <- data.frame(trt,qw,tr)
df %>%
group_by(trt) %>%
summarise(mean.mpg = mean(qw, na.rm = TRUE),
sd.mpg = sd(qw, na.rm = TRUE),
n.mpg = n())%>%
mutate(se.mpg = sd.mpg / sqrt(n.mpg),
lower.ci.mpg = mean.mpg - qt(1 - (0.05 / 2), n.mpg - 1) * se.mpg,
upper.ci.mpg = mean.mpg + qt(1 - (0.05 / 2), n.mpg - 1) * se.mpg)
现在引用我们创建的新 DataTable 对象。
这个答案更详细,其评论也值得一读:https://stackoverflow.com/a/80113/13924556
答案 2 :(得分:0)
也许它对某人有用:
在向 DataGrid(WPF) 添加项目之前,如果您想在将来获得非空的 DataGridRow,要更改一些属性,例如 Background,您需要创建新的 DataGridRow 对象,将您的类分配给 DataGridRow.Item 属性,然后添加到 DataGrid。
像这样:
DataGridRow mRow = new DataGridRow();
mRow.Item = YOUR_DATA_CLASS;
_ = datagrid.Items.Add(mRow);
答案 3 :(得分:-2)
for(int row =0; row < dg_CountInventory.Rows.Count; row ++) //Loop through each row
{
//Provide the Column Index and row as in Loop
TextBlock b = dg_CountInventory.Columns[1].GetCellContent(dg_CountInventory.Items[row ]) as TextBlock;
}
dg_CountInventory是我的网格名称。此代码将遍历所有记录 存在于数据网格和单元/列提供中。#