从 DGV C# 中的查询复制列 header
duplicating column header from query in a DGV C#
我 运行 遇到了一个问题,我正在寻找解决问题的最佳方法。我正在编写一个工作流管理程序,但我卡在了某个部分。基本上我所拥有的就是这个。我可以查询所有产品,并将它们显示在 DGV 中(在产品搜索 Class 中。一旦他们单击复选框然后点击 selected 按钮,所有产品都会转移到不同的DGV 在不同的 class(Quotes class) 中。一切正常。
我遇到的问题是,如果他们想返回 select 另一个项目,一旦它转移到引号 class,列 headers 就会重复。为了解决这个问题,我正在尝试将我拥有的行(在引号 class DGV 中)复制到列表中。然后我还想将新的 selected 项目添加到列表中,然后将该列表设置为我的数据源。
我让它复制所有信息(我可以显示值,因为它将单元格值复制到列表中)它只是不会显示 DGV 中的值,但确实出现了正确的行数(当我出现空引用错误时尝试获取单元格值
首先有没有更好的方法来做到这一点?
其次有没有办法使这项工作?
我会 post 我的代码。
DataGridView targetGrid = this.Q_MatDGV;
列出 AddRows;
if (material.RowSelected)
{
//Checks to see if there are any rows in the material DGV already.
if (Q_MatDGV.Rows.Count > 0)
{
//TODO: Make it so if you have to add a new item then the column headers don't get added again.
//I think you need to make a new array list then rebind the DGV after it's cleared out.
// Loop through the info that is already in the table and then you will have to get the data from the material.sourcegrid.columns and add that to the array list
// once that is done we can then re link the dataset to the old DGV.
var source = new BindingSource();
sourceGrid = this.Q_MatDGV; ;
AddRows = new List<DataGridViewRow>();
foreach (DataGridViewRow sourceRow in sourceGrid.Rows)
{
if (Convert.ToBoolean(sourceRow.Cells["CheckBox"].Value) == true)
{
if (!sourceRow.IsNewRow)
{
var targetRow = (DataGridViewRow)sourceRow.Clone();
foreach (DataGridViewCell cell in sourceRow.Cells)
{
targetRow.Cells[cell.ColumnIndex].Value = cell.Value;
// MessageBox.Show(cell.Value.ToString());
}
AddRows.Add(targetRow);
}
}
}
foreach(DataGridViewRow row in material.SourceGrid.Rows)
{
if (Convert.ToBoolean(row.Cells["CheckBox"].Value) == true)
{
AddRows.Add((DataGridViewRow)row.Clone());
}
}
source.DataSource = AddRows;
// Q_MatDGV.DataSource = null;
// Q_MatDGV.Rows.Clear();
Q_MatDGV.DataSource = source;
MessageBox.Show(Q_MatDGV.Rows.Count.ToString());
MessageBox.Show(Q_MatDGV.Rows[1].Cells[2].Value.ToString());
}
是的,有更好的方法。创建一个全新的项目并将其粘贴到 Form1 构造函数的顶部
public Form1()
{
InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Chosen", typeof(bool));
dt.Rows.Add("Matthew", true);
dt.Rows.Add("Mark", false);
dt.Rows.Add("Luke", false);
dt.Rows.Add("John", false);
var nonChosenDV = new DataView(dt);
nonChosenDV.RowFilter = "[Chosen] = false";
var chosenDV = new DataView(dt);
chosenDV.RowFilter = "[Chosen] = true";
var nonChosenDgv = new DataGridView();
nonChosenDgv.DataSource = nonChosenDV;
var chosenDgv = new DataGridView();
chosenDgv.DataSource = chosenDV;
var chosenF = new Form();
chosenF.Text = "Only the chosen ones";
chosenF.Controls.Add(chosenDgv);
chosenF.Show();
var nonChosenF = new Form();
nonChosenF.Text = "These guys don't make the cut";
nonChosenF.Controls.Add(nonChosenDgv);
nonChosenF.Show();
//add a dgv to this form to show all the data all the time
var allDgv = new DataGridView();
allDgv.DataSource = dt; //it will bind to the dt.DefaultView by the way
this.Controls.Add(allDgv);
this.Text = "All the raw data";
}
在这里,我们可以创建一个包含一些 string/bool 列的数据表(您的数据所在的模型)——为了简单起见,您应该在数据集设计器中创建实际的数据表,但是这不是那么容易粘贴的,因此我选择了无类型的路线
然后我们将这个相同的通用数据模型连接到 3 种不同形式的 3 个不同 DGV,每个 DGV 通过执行不同过滤的不同 DataView 读取数据
因为我们使用通用数据模型,所以更改任何网格中的任何复选框都会导致(当通过导航到另一行提交该行时)事务状态更新,以便一个网格始终显示 true,一个显示错误(一个网格显示所有内容,您会看到刻度打开和关闭)
我把它作为单独的表格来做,因为你说“单独的 class”- class 和这种情况下的表格没有区别
客观教训是,DataGridView 不应该是您将数据推入其中的东西。您通过 DGV 将数据保存在其他地方(如数据表)和 show/interact(在用户点击和键入的意义上),但如果您想以编程方式与它交互,您可以从数据表中获取它,而不是视图(在非常特殊的情况下除外)。
如果您需要执行诸如“访问当前行”之类的操作,您可以通过 BindingSource 进行操作。如果用户选择了 10 行;你得到 10 行并向他们询问他们的 databounditem,它给出了数据表中的数据行(它给出了一个 DataRowView,它有一个 .Row,它是一个 DataRow,需要一些转换)。您不通过 Cell.Value
拖出数据
我 运行 遇到了一个问题,我正在寻找解决问题的最佳方法。我正在编写一个工作流管理程序,但我卡在了某个部分。基本上我所拥有的就是这个。我可以查询所有产品,并将它们显示在 DGV 中(在产品搜索 Class 中。一旦他们单击复选框然后点击 selected 按钮,所有产品都会转移到不同的DGV 在不同的 class(Quotes class) 中。一切正常。 我遇到的问题是,如果他们想返回 select 另一个项目,一旦它转移到引号 class,列 headers 就会重复。为了解决这个问题,我正在尝试将我拥有的行(在引号 class DGV 中)复制到列表中。然后我还想将新的 selected 项目添加到列表中,然后将该列表设置为我的数据源。 我让它复制所有信息(我可以显示值,因为它将单元格值复制到列表中)它只是不会显示 DGV 中的值,但确实出现了正确的行数(当我出现空引用错误时尝试获取单元格值
首先有没有更好的方法来做到这一点? 其次有没有办法使这项工作? 我会 post 我的代码。
DataGridView targetGrid = this.Q_MatDGV; 列出 AddRows;
if (material.RowSelected)
{
//Checks to see if there are any rows in the material DGV already.
if (Q_MatDGV.Rows.Count > 0)
{
//TODO: Make it so if you have to add a new item then the column headers don't get added again.
//I think you need to make a new array list then rebind the DGV after it's cleared out.
// Loop through the info that is already in the table and then you will have to get the data from the material.sourcegrid.columns and add that to the array list
// once that is done we can then re link the dataset to the old DGV.
var source = new BindingSource();
sourceGrid = this.Q_MatDGV; ;
AddRows = new List<DataGridViewRow>();
foreach (DataGridViewRow sourceRow in sourceGrid.Rows)
{
if (Convert.ToBoolean(sourceRow.Cells["CheckBox"].Value) == true)
{
if (!sourceRow.IsNewRow)
{
var targetRow = (DataGridViewRow)sourceRow.Clone();
foreach (DataGridViewCell cell in sourceRow.Cells)
{
targetRow.Cells[cell.ColumnIndex].Value = cell.Value;
// MessageBox.Show(cell.Value.ToString());
}
AddRows.Add(targetRow);
}
}
}
foreach(DataGridViewRow row in material.SourceGrid.Rows)
{
if (Convert.ToBoolean(row.Cells["CheckBox"].Value) == true)
{
AddRows.Add((DataGridViewRow)row.Clone());
}
}
source.DataSource = AddRows;
// Q_MatDGV.DataSource = null;
// Q_MatDGV.Rows.Clear();
Q_MatDGV.DataSource = source;
MessageBox.Show(Q_MatDGV.Rows.Count.ToString());
MessageBox.Show(Q_MatDGV.Rows[1].Cells[2].Value.ToString());
}
是的,有更好的方法。创建一个全新的项目并将其粘贴到 Form1 构造函数的顶部
public Form1()
{
InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Chosen", typeof(bool));
dt.Rows.Add("Matthew", true);
dt.Rows.Add("Mark", false);
dt.Rows.Add("Luke", false);
dt.Rows.Add("John", false);
var nonChosenDV = new DataView(dt);
nonChosenDV.RowFilter = "[Chosen] = false";
var chosenDV = new DataView(dt);
chosenDV.RowFilter = "[Chosen] = true";
var nonChosenDgv = new DataGridView();
nonChosenDgv.DataSource = nonChosenDV;
var chosenDgv = new DataGridView();
chosenDgv.DataSource = chosenDV;
var chosenF = new Form();
chosenF.Text = "Only the chosen ones";
chosenF.Controls.Add(chosenDgv);
chosenF.Show();
var nonChosenF = new Form();
nonChosenF.Text = "These guys don't make the cut";
nonChosenF.Controls.Add(nonChosenDgv);
nonChosenF.Show();
//add a dgv to this form to show all the data all the time
var allDgv = new DataGridView();
allDgv.DataSource = dt; //it will bind to the dt.DefaultView by the way
this.Controls.Add(allDgv);
this.Text = "All the raw data";
}
在这里,我们可以创建一个包含一些 string/bool 列的数据表(您的数据所在的模型)——为了简单起见,您应该在数据集设计器中创建实际的数据表,但是这不是那么容易粘贴的,因此我选择了无类型的路线
然后我们将这个相同的通用数据模型连接到 3 种不同形式的 3 个不同 DGV,每个 DGV 通过执行不同过滤的不同 DataView 读取数据
因为我们使用通用数据模型,所以更改任何网格中的任何复选框都会导致(当通过导航到另一行提交该行时)事务状态更新,以便一个网格始终显示 true,一个显示错误(一个网格显示所有内容,您会看到刻度打开和关闭)
我把它作为单独的表格来做,因为你说“单独的 class”- class 和这种情况下的表格没有区别
客观教训是,DataGridView 不应该是您将数据推入其中的东西。您通过 DGV 将数据保存在其他地方(如数据表)和 show/interact(在用户点击和键入的意义上),但如果您想以编程方式与它交互,您可以从数据表中获取它,而不是视图(在非常特殊的情况下除外)。
如果您需要执行诸如“访问当前行”之类的操作,您可以通过 BindingSource 进行操作。如果用户选择了 10 行;你得到 10 行并向他们询问他们的 databounditem,它给出了数据表中的数据行(它给出了一个 DataRowView,它有一个 .Row,它是一个 DataRow,需要一些转换)。您不通过 Cell.Value
拖出数据