在WPF中以编程方式更改DataGrid单元格的值

7

我有一个 DataGrid 视图,它在运行时通过列表填充其内容。我想要更改(例如)第2行第3列的单元格值。

我该如何做到这一点?

2个回答

13

这并不复杂。

你需要一些辅助函数;

public static T GetVisualChild<T>(Visual parent) where T : Visual
{
    T child = default(T);
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
       if (child != null)
       {
           break;
       }
   }
       return child;
}

public static DataGridRow GetSelectedRow(this DataGrid grid)
{
    return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
}
public static DataGridRow GetRow(this DataGrid grid, int index)
{
    DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    if (row == null)
    {
        // May be virtualized, bring into view and try again.
        grid.UpdateLayout();
        grid.ScrollIntoView(grid.Items[index]);
        row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    }
    return row;
}

public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
    if (row != null)
    {
        DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);

        if (presenter == null)
        {
            grid.ScrollIntoView(row, grid.Columns[column]);
            presenter = GetVisualChild<DataGridCellsPresenter>(row);
        }

        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
        return cell;
    }
    return null;
}

public static DataGridCell GetCell(this DataGrid grid, int row, int column)
{
    DataGridRow rowContainer = grid.GetRow(row);
    return grid.GetCell(rowContainer, column);
}

使用yourDataGrid.GetCell(5, 3).Content = "任何你想要的内容";

14
这是个玩笑,对吧?以前在Winforms中只需要一行代码就能获取/设置Datagridview的值! - チーズパン
2
@bodycountPP,很遗憾不能这样做。事实上,你不应该通过编程方式更改单元格的值——这不是WPF的用途,WPF不是WinForms的替代品或升级版,它是一种新的创新。请查看DataGridView和MVVM,了解商业应用程序中应该如何处理事情。 - Erti-Chris Eelmaa
GetVisualChild 总是返回 null。为什么呢? - ThEpRoGrAmMiNgNoOb
这个可以工作,但是如果你改变了一堆值,这些值会在你离开后立即恢复到它们的原始形式。如果你选择单元格并滚动,然后再滚回来,它将保留你分配的值,但其他单元格将恢复到它们的原始值...很奇怪。 - Zoey

2
例如,如果您在网格上有一个文本框(TextBox)
<TextBox  Grid.Row="2" Grid.Column="3" Text="{Binding ...}"/>

完整示例

<Grid x:Name="RootElement">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>

      <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
      </Grid.RowDefinitions>

      ...
      <TextBox  Grid.Row="2" Grid.Column="3" Text="{Binding ...}"/>
      ...
    </Grid>

你可以使用这些辅助工具;你有这个链接http://techiethings.blogspot.fr/2010/05/get-wpf-datagrid-row-and-cell.html
我添加了代码以便在stackoverflow关闭的情况下节省代码。
public static DataGridRow GetRow(this DataGrid grid, int index)
{
    DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    if (row == null)
    {
        // May be virtualized, bring into view and try again.
        grid.UpdateLayout();
        grid.ScrollIntoView(grid.Items[index]);
        row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    }
    return row;
}

public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
    if (row != null)
    {
        DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);

        if (presenter == null)
        {
            grid.ScrollIntoView(row, grid.Columns[column]);
            presenter = GetVisualChild<DataGridCellsPresenter>(row);
        }

        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
        return cell;
    }
    return null;
}

public static DataGridCell GetCell(this DataGrid grid, int row, int column)
{
    DataGridRow rowContainer = grid.GetRow(row);
    return grid.GetCell(rowContainer, column);
}

我想以编程的方式来实现,我的选择不是固定的,每次选择不同的单元格,我该怎么做? - KF2
1
一切都正常,但当我移动网关滚动条时,数据会消失。问题出在哪里? - KF2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接