【发布时间】:2014-03-16 15:30:37
【问题描述】:
我想在不使用任何循环的情况下将所有数据网格记录复制到数据表中。 例如:
Dim dt as New DataTable
dt = Datagrid1.Items
但这不起作用并给出错误消息。
我的开发平台是 Visual Studio 2010,语言是 WPF 和 vb.net 4.0
【问题讨论】:
标签: wpf vb.net wpfdatagrid wpf-4.0
我想在不使用任何循环的情况下将所有数据网格记录复制到数据表中。 例如:
Dim dt as New DataTable
dt = Datagrid1.Items
但这不起作用并给出错误消息。
我的开发平台是 Visual Studio 2010,语言是 WPF 和 vb.net 4.0
【问题讨论】:
标签: wpf vb.net wpfdatagrid wpf-4.0
这是在不使用 LOOP 的情况下将所有记录从 DATAGRID 传输到 DATATABLE 的方法。
VB:
Dim dt As New DataTable
dt = CType(DataGrid1.ItemsSource, DataView).ToTable
C#:
DataTable dt = new DataTable();
dt = ((DataView)DataGrid1.ItemsSource).ToTable();
【讨论】:
这取决于数据网格的填充方式。如果 DataContext 属性设置为 DataTable,那么您只需检索该值并强制转换为 DataTable。
没有直接的方法可以将它从 DataGrid 元素转换为 DataTable。
如果您想手动执行此操作,则必须创建 DataTable 的实例,然后使用循环从 DataGrid 中的项目创建行。
【讨论】:
要将您的 dataGrid 转换为带有标题行的数据表,您可以按照以下步骤操作:
1) 创建检索单元格的方法
static public DataGridCell GetCell(DataGrid dg, int row, int column)
{
DataGridRow rowContainer = GetRow(dg, row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
if (cell == null)
{
dg.ScrollIntoView(rowContainer, dg.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
}
return cell;
}
return null;
}
2) 遍历所有项目并将内容传递给数据表“单元格”
private void DataGridToDataTable()
{
DataTable dt = new DataTable();
var j = byte.MinValue;//header row handler
dt.Rows.Add();
foreach (DataGridColumn column in dataGrid1.Columns)
{
dt.Columns.Add(column.GetValue(NameProperty).ToString());
dt.Rows[byte.MinValue][j++] = column.Header;
}
//data rows handler
for (int i = byte.MinValue ; i < dataGrid1.Items.Count; i++)
{
dt.Rows.Add();
for (j = Byte.MinValue; j < dataGrid1.Columns.Count; j++)
{
DataGridCell dgc = GetCell(dataGrid1, i, j);
dt.Rows[i + 1][j] = ((dgc.Content) as TextBlock).Text;
}
}
}
记住要使用这个方法,你必须引用它
using System.Windows.Media;
using System.Data;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
这里有一个帮助类来使用它。
/// <summary>
/// Class to help to retrive the Data Grid Contain
/// </summary>
public static class DataGridHelper
{
/// <summary>
/// Retrive the cell contains
/// </summary>
/// <param name="dg">DataGrid</param>
/// <param name="row">row</param>
/// <param name="column">column</param>
/// <returns>DataGrid Cell content</returns>
static public DataGridCell GetCell(DataGrid dg, int row, int column)
{
DataGridRow rowContainer = GetRow(dg, row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
// try to get the cell but it may possibly be virtualized
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
if (cell == null)
{
// now try to bring into view and retreive the cell
dg.ScrollIntoView(rowContainer, dg.Columns[column]);
cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
}
return cell;
}
return null;
}
/// <summary>
/// Get row content
/// </summary>
/// <param name="dg">Datagrid</param>
/// <param name="index">Index</param>
/// <returns>DataGridRow</returns>
static public DataGridRow GetRow(DataGrid dg, int index)
{
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
dg.ScrollIntoView(dg.Items[index]);
row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
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;
}
}
【讨论】:
我刚刚测试了这个,它可以工作
Dim dt as New DataTable
dt = ctype(Datagrid1.Datasource, DataTable)
【讨论】:
您必须在 DataGrid 上循环并将项目添加到 Datatable。下面的链接可能会有所帮助。
【讨论】: