当 datagridview 选择中存在 NUL 字符时,为什么复制粘贴不起作用?
Why won't copy paste work when NUL character is present in datagridview selection?
如果存在 "NUL" 个字符(即 ASCII 代码 = 0),为什么任何形式的 copy/paste datagridview 都不起作用?如果数据中存在 "NUL" 个字符,datagridview 会将它们显示为空格,但不会复制(或至少不会粘贴)超出它们的实例。我不确定我是否发现了错误,或者我只是不理解剪贴板/copy/paste 的行为。手动 copy/paste 和编程方法都产生相同的结果。如果手动 selects,它会出现 select 多行,但是当粘贴时,只会粘贴第一个 "NUL" 字符之前的数据。该行和所有其他行上的其余数据未粘贴。
None 的 row/edit 设置似乎很重要。在单元格中生成数据的方法似乎并不重要。我搜索了 Google 和 S.O。对于一个没有用的答案。是的,我确实看到了 S.O。帖子 Copy string data with NULL character inside string to char array and NULL in a string can't copy contents after NUL 和一些类似的帖子 none 回答了这个问题——它们只提供涉及替换 NUL 字符的解决方法。我希望能理解 "why" 并找到 copy/paste 包括 NUL 字符的方法。
我创建了一个纯测试场景。抱歉,如果我包含了太多内容。我不完全确定 required/relevant 是什么,所以我犯了太多的错误。
using System;
using System.Data;
using System.Windows.Forms;
namespace GQ
{
public partial class frmTestOfDataGrid : Form
{
public frmTestOfDataGrid()
{
InitializeComponent();
}
private void buttonRunTest_Click(object sender, EventArgs e)
{
BindingSource myBindingSource = new BindingSource();
myBindingSource.DataSource = CreateTestDataTable();
dataGridView1.DataSource = myBindingSource;
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
private DataTable CreateTestDataTable()
{
char Nul = (char)0;
string myTestString1 = "The Nul characters are between these >" + Nul + Nul + "< and you can't copy anything after them.";
string myTestString2 = "Second line of test data will not end up being copied to clipboard if above Nul characters are included in selection.";
DataTable tbl = new DataTable();
tbl.Columns.Add("RowIndex", typeof(Int32));
tbl.Columns.Add("RowValue", typeof(String));
DataRow dr1 = tbl.NewRow();
dr1[0] = 0;
dr1[1] = myTestString1;
tbl.Rows.Add(dr1);
DataRow dr2 = tbl.NewRow();
dr2[0] = 1Y;
dr2[1] = myTestString2;
tbl.Rows.Add(dr2);
return tbl;
}
private void buttonCopyToClipboard_Click(object sender, EventArgs e)
{
if (this.dataGridView1
.GetCellCount(DataGridViewElementStates.Selected) > 0)
{
Clipboard.SetDataObject(this.dataGridView1.GetClipboardContent());
}
}
}
}
namespace GQ
{
partial class frmTestOfDataGrid
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.buttonRunTest = new System.Windows.Forms.Button();
this.buttonCopyToClipboard = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Location = new System.Drawing.Point(10, 43);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
this.dataGridView1.Size = new System.Drawing.Size(963, 313);
this.dataGridView1.TabIndex = 0;
//
// buttonRunTest
//
this.buttonRunTest.Location = new System.Drawing.Point(753, 371);
this.buttonRunTest.Name = "buttonRunTest";
this.buttonRunTest.Size = new System.Drawing.Size(146, 27);
this.buttonRunTest.TabIndex = 1;
this.buttonRunTest.Text = "Run Test";
this.buttonRunTest.UseVisualStyleBackColor = true;
this.buttonRunTest.Click += new System.EventHandler(this.buttonRunTest_Click);
//
// buttonCopyToClipboard
//
this.buttonCopyToClipboard.Location = new System.Drawing.Point(753, 403);
this.buttonCopyToClipboard.Name = "buttonCopyToClipboard";
this.buttonCopyToClipboard.Size = new System.Drawing.Size(146, 27);
this.buttonCopyToClipboard.TabIndex = 2;
this.buttonCopyToClipboard.Text = "Then Copy To Clipboard";
this.buttonCopyToClipboard.UseVisualStyleBackColor = true;
this.buttonCopyToClipboard.Click += new System.EventHandler(this.buttonCopyToClipboard_Click);
//
// frmTestOfDataGrid
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(976, 442);
this.Controls.Add(this.buttonCopyToClipboard);
this.Controls.Add(this.buttonRunTest);
this.Controls.Add(this.dataGridView1);
this.Name = "frmTestOfDataGrid";
this.Text = "frmTestOfDataGrid";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.Button buttonRunTest;
private System.Windows.Forms.Button buttonCopyToClipboard;
}
}
(char)0 或 '\0' 基本上是字符串的结尾。这就是为什么 copy 不会拿走之后的任何东西。
我在你的句子中换行显示两个字符
而且从网格来看,还是可以copy/paste的。
('\0')的用法很不寻常,我很想知道使用它的原因是什么?
您可以在 Why do we need to add a '[=13=]' (null) at the end of a character array in C?
上看到讨论
如果存在 "NUL" 个字符(即 ASCII 代码 = 0),为什么任何形式的 copy/paste datagridview 都不起作用?如果数据中存在 "NUL" 个字符,datagridview 会将它们显示为空格,但不会复制(或至少不会粘贴)超出它们的实例。我不确定我是否发现了错误,或者我只是不理解剪贴板/copy/paste 的行为。手动 copy/paste 和编程方法都产生相同的结果。如果手动 selects,它会出现 select 多行,但是当粘贴时,只会粘贴第一个 "NUL" 字符之前的数据。该行和所有其他行上的其余数据未粘贴。
None 的 row/edit 设置似乎很重要。在单元格中生成数据的方法似乎并不重要。我搜索了 Google 和 S.O。对于一个没有用的答案。是的,我确实看到了 S.O。帖子 Copy string data with NULL character inside string to char array and NULL in a string can't copy contents after NUL 和一些类似的帖子 none 回答了这个问题——它们只提供涉及替换 NUL 字符的解决方法。我希望能理解 "why" 并找到 copy/paste 包括 NUL 字符的方法。
我创建了一个纯测试场景。抱歉,如果我包含了太多内容。我不完全确定 required/relevant 是什么,所以我犯了太多的错误。
using System;
using System.Data;
using System.Windows.Forms;
namespace GQ
{
public partial class frmTestOfDataGrid : Form
{
public frmTestOfDataGrid()
{
InitializeComponent();
}
private void buttonRunTest_Click(object sender, EventArgs e)
{
BindingSource myBindingSource = new BindingSource();
myBindingSource.DataSource = CreateTestDataTable();
dataGridView1.DataSource = myBindingSource;
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
private DataTable CreateTestDataTable()
{
char Nul = (char)0;
string myTestString1 = "The Nul characters are between these >" + Nul + Nul + "< and you can't copy anything after them.";
string myTestString2 = "Second line of test data will not end up being copied to clipboard if above Nul characters are included in selection.";
DataTable tbl = new DataTable();
tbl.Columns.Add("RowIndex", typeof(Int32));
tbl.Columns.Add("RowValue", typeof(String));
DataRow dr1 = tbl.NewRow();
dr1[0] = 0;
dr1[1] = myTestString1;
tbl.Rows.Add(dr1);
DataRow dr2 = tbl.NewRow();
dr2[0] = 1Y;
dr2[1] = myTestString2;
tbl.Rows.Add(dr2);
return tbl;
}
private void buttonCopyToClipboard_Click(object sender, EventArgs e)
{
if (this.dataGridView1
.GetCellCount(DataGridViewElementStates.Selected) > 0)
{
Clipboard.SetDataObject(this.dataGridView1.GetClipboardContent());
}
}
}
}
namespace GQ
{
partial class frmTestOfDataGrid
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.buttonRunTest = new System.Windows.Forms.Button();
this.buttonCopyToClipboard = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Location = new System.Drawing.Point(10, 43);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.ReadOnly = true;
this.dataGridView1.Size = new System.Drawing.Size(963, 313);
this.dataGridView1.TabIndex = 0;
//
// buttonRunTest
//
this.buttonRunTest.Location = new System.Drawing.Point(753, 371);
this.buttonRunTest.Name = "buttonRunTest";
this.buttonRunTest.Size = new System.Drawing.Size(146, 27);
this.buttonRunTest.TabIndex = 1;
this.buttonRunTest.Text = "Run Test";
this.buttonRunTest.UseVisualStyleBackColor = true;
this.buttonRunTest.Click += new System.EventHandler(this.buttonRunTest_Click);
//
// buttonCopyToClipboard
//
this.buttonCopyToClipboard.Location = new System.Drawing.Point(753, 403);
this.buttonCopyToClipboard.Name = "buttonCopyToClipboard";
this.buttonCopyToClipboard.Size = new System.Drawing.Size(146, 27);
this.buttonCopyToClipboard.TabIndex = 2;
this.buttonCopyToClipboard.Text = "Then Copy To Clipboard";
this.buttonCopyToClipboard.UseVisualStyleBackColor = true;
this.buttonCopyToClipboard.Click += new System.EventHandler(this.buttonCopyToClipboard_Click);
//
// frmTestOfDataGrid
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(976, 442);
this.Controls.Add(this.buttonCopyToClipboard);
this.Controls.Add(this.buttonRunTest);
this.Controls.Add(this.dataGridView1);
this.Name = "frmTestOfDataGrid";
this.Text = "frmTestOfDataGrid";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.Button buttonRunTest;
private System.Windows.Forms.Button buttonCopyToClipboard;
}
}
(char)0 或 '\0' 基本上是字符串的结尾。这就是为什么 copy 不会拿走之后的任何东西。
我在你的句子中换行显示两个字符
而且从网格来看,还是可以copy/paste的。
('\0')的用法很不寻常,我很想知道使用它的原因是什么?
您可以在 Why do we need to add a '[=13=]' (null) at the end of a character array in C?
上看到讨论