C# 获取数据网格中的行

C# 获取数据网格中的行,c#,wpf,datagrid,row,C#,Wpf,Datagrid,Row,我试着这样划船: DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i); TextBlock cellContent = dataGrid.Columns[0].GetCellContent(row) as TextBlock; 但我只得到了null。还有别的解决办法吗?我做错了什么 我想从我的手机里获取数据。我的单元格是复选框。这取决于您尝试获取此数据的方式/时间。WPF更倾向

我试着这样划船:

DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
TextBlock cellContent = dataGrid.Columns[0].GetCellContent(row) as TextBlock;
但我只得到了
null
。还有别的解决办法吗?我做错了什么


我想从我的手机里获取数据。我的单元格是复选框。

这取决于您尝试获取此数据的方式/时间。WPF更倾向于通过ItemsSource中绑定的对象访问数据。因此,如果ItemsSource是MyObject的列表,那么特定行的类型将是MyObject,而不是纯DataRow

如果您通过单击数据访问数据,可以执行以下操作:

var currentItem = myDataGrid.SelectedItem as MyObject;
现在,您将当前MyObject设置为其最初的预期形式,而不是在网格中拾取。

for(int row=0;row  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; 
    }
{ //在循环中提供列索引和行 TextBlock b=dg_CountInventory.Columns[1].GetCellContent(dg_CountInventory.Items[row])作为TextBlock; } dg_CountInventory是我的网格名称。此代码将在所有记录中循环 显示在数据网格和提供的单元格/列中。#

获取
DataGrid
以获取适当的数据对象进行操作: 由于
DataGrid
以绑定到数据对象的原则进行操作,因此您需要在类似
DataTable
的东西中跟踪数据

例如,为DataTable类型的MainWindow类初始化一个字段,并将其命名为相关名称:

public partial class MainWindow : Window
{
    private DataTable _cars = new DataTable("Cars");
然后在构造函数中,初始化窗口组件后,将
DataGrid.ItemSource
作为数据视图绑定到DataTable的集合:

    public MainWindow()
    {
        InitializeComponent();

        dgCars.ItemsSource = _cars.AsDataView();
    }
现在,无论何时以编程方式向
\u cars
表中添加新行,它们都将反映在
数据网格中,耶!但是,您希望能够从用户界面对数据进行操作,所以让我们开始吧

使用来自用户界面的输入操作
数据表
中的数据: 当您想要对数据进行操作时,可以从
数据网格
中的项目中获取所选内容,并使用它们提供的索引从
数据表
中删除项目,然后重新应用数据视图。这是总结,但我将更详细地介绍并完成示例:

  • 在执行逻辑之前,我们需要迭代每个
    DataGrid
    项,并检查它是否被选中:

        for (int i = 0; i < dgCars.Items.Count; i++)
        {
            if (dgCars.SelectedItems.Contains(dgCars.Items[i]))
            {
                // This is where we do the magic
            }
        }
    
  • 同样,我们会遇到IndexOutOfBounds错误,因为我们对数据进行迭代,就好像存在
    X
    数据量一样,但每次删除(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
            }
        }
    
  • 成品: 我们在这里构建的这个示例允许您通过用鼠标选择数据网格上的行,然后单击一个按钮从数据网格中删除数据,该按钮的值等于
    btnRemove\u Click
    。简单的修改和逻辑更改将允许您对添加、编辑等数据执行相同的操作,但遵循我们最初开始的原则,即对数据对象(在本例中为
    DataTable
    )进行操作,并使该项成为
    DataGrid
    ItemsSource
    公共部分类主窗口:窗口
    {
    私有数据表(cars=新数据表(“cars”);
    公共主窗口()
    {
    初始化组件();
    //这不在构建示例中,但作为奖励:
    //我们还可以利用这个机会设置静态
    //列标题,如果我们事先知道它们是什么!
    _汽车。栏。加上(“年”);
    _汽车。列。添加(“制造”);
    _汽车.立柱.添加(“模型”);
    dgCars.ItemsSource=_cars.AsDataView();
    }
    专用BTN删除\单击(对象发送者,路由目标e)
    {
    int=0;
    DataTable结果=_cars.Copy();
    对于(int i=0;i

    -额外阅读- 在步骤4的前面,我提到:

    最后,但并非最不重要的是,我们将把
    \u cars
    变量指向
    结果
    然后重新分配
    dgCars.ItemSource=\u cars.AsDataView()
    以更新数据网格

    这是因为
    \u cars
    result
    都是从类中实例化的对象,因此它们位于堆中。当堆栈上不再有对堆上的项的引用时,堆上的项将被垃圾收集(从内存中删除)。由于
    \u cars
    是我们的
    主窗口的一个字段
    ,并且继续在
    btnRemove\u Click
    的范围之外,当我们将其指向
    数据表结果时,我们保留对该表的引用,并将引用删除到原始表。因此,当
    btnRemove\u单击
    完成时,变量
    结果
    被垃圾收集,用于指向的旧
    数据表
    被垃圾收集,而
    \u cars
    现在引用我们创建的新数据表对象

    这个答案更为详细,其注释也值得一读:

    检查此解决方案没有
    属性。
        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
            }
        }
    
        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
    
    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();
        }
    }