我有一个DataGridView
使用DataTable
绑定到BindingSource
,并且DataGridView
中的所有列都不都绑定到该DataSource
的属性。更具体地说,我有一个自定义DataGridViewColumn
的自定义DataGridViewCheckBoxColumn
派生自DataTable.AcceptChanges
类,并具有一个主复选框,该复选框控制列标题中的其他复选框。我的问题是,每当调用DataGridViewCheckBoxCell
时,DataTable.AcceptChanges
都会恢复为默认值(False),而我失去了先前的选择。有谁知道防止或避免这种行为的好方法?
从本质上讲,即使在调用Ctrl+S
之后,我仍然希望保留该列中的单元格值,因为它们与基础数据源无关。
这是一些示例代码,可重现我的经验。选中选择列中的某些复选框,然后按DataGridViewColumn
,请注意,即使它们未绑定到特定的BindingSource
,您也会每次都丢失它们。我意识到这可能是AcceptChanges
的本质,但是我想知道是否有解决此问题的方法。另外,我想避免编写逻辑来保存在调用AcceptChanges
之前选择了哪些行,然后在DataGridView
返回之后将其重置的逻辑。对我来说,如果一次在Public Class Form1
Sub New()
InitializeComponent()
Dim dgv As New DataGridView
dgv.Columns.Add(New DataGridViewCheckBoxColumn With {.HeaderText = "Selection"})
dgv.Columns.Add(New DataGridViewTextBoxColumn With {.HeaderText = "ChangeMe", .DataPropertyName = "ChangeMe"})
Controls.Add(dgv) : dgv.Dock = DockStyle.Fill
Dim dt = New DataTable : dt.Columns.Add("ChangeMe", GetType(String))
For Each thing In {"Shoe", "Boat", "Rat"} : dt.Rows.Add(thing) : Next
dgv.DataSource = New BindingSource(dt, Nothing)
Me.KeyPreview = True
AddHandler Me.KeyDown, Sub(sender As Object, e As KeyEventArgs)
If e.Control AndAlso e.KeyCode = Keys.S Then dt.AcceptChanges()
End Sub
End Sub
End Class
中选择了很多行,这似乎太麻烦了。有人有一个更骇人听闻的主意吗?
public class SumatraWrapper : IDisposable
{
private readonly FileInfo _tempFileForExe = null;
private readonly FileInfo _exe = null;
public SumatraWrapper()
{
_exe = ExtractExe();
}
public SumatraWrapper(FileInfo tempFileForExe)
: this()
{
_tempFileForExe = tempFileForExe ?? throw new ArgumentNullException(nameof(tempFileForExe));
}
private FileInfo ExtractExe()
{
string tempfile =
_tempFileForExe != null ?
_tempFileForExe.FullName :
Path.GetTempFileName() + ".exe";
FileInfo exe = new FileInfo(tempfile);
byte[] bytes = Properties.Resources.SumatraPDF;
using (FileStream fs = exe.OpenWrite())
{
fs.Write(bytes, 0, bytes.Length);
}
return exe;
}
public bool Print(FileInfo file, string printerName)
{
string arguments = $"-print-to \"{printerName}\" \"{file.FullName}\"";
ProcessStartInfo processStartInfo = new ProcessStartInfo(_exe.FullName, arguments)
{
CreateNoWindow = true
};
using (Process process = Process.Start(processStartInfo))
{
process.WaitForExit();
return process.ExitCode == 0;
}
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
try
{
File.Delete(_exe.FullName);
}
catch
{
}
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~PdfToPrinterWrapper() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
答案 0 :(得分:0)
此问题是由port 9000,
响应于BindingSource
方法而引发类型为ListChangedType.Reset
的{{3}}引起的。 DataTable.AcceptChanges
收到此事件后,将从DataGridView
重新加载,这在BindingSource.ListChanged Event中发生(向下滚动到第658行)。
一种可能的解决方法是通过修改以下密钥处理程序方法来防止BindingSource.
在执行BindingSource
期间引发事件。
DataTable.AcceptChanges