データ テーブルとして機能する xml ファイルがあります。さまざまな種類のデータを保持します。データ型は、どの列でも異なる可能性があります。例は次のとおりです。row(1)String, int, date; 行 (2) バイナリ、整数、日付; 行 (3) 文字列、バイナリ、整数。
これは、私が解決しようとしている問題につながります.セルの内容を解析し、データ型がバイナリまたはバイト型であるセルにボタンを配置するにはどうすればよいですか.
すべてのセルの内容が異なるタイプであるだけでなく、セルが列タイプに自動的に割り当てられず、手動で行う必要があるため、これは注意が必要です。
これを達成する方法についてのアイデアはありますか?
PS CellValidating イベントを使用すると、必要な動作を得ることができると思いますが、文字列が実際にバイナリ データであることを検証する方法に途方に暮れています...
編集: わかりましたので、目的の結果を得る最も簡単な方法は、記録するデータの種類をユーザーに選択させることであると判断しました。その後、各列でそのデータ型を確認し、そのデータ型が列に存在する場合はボタンを配置します。
シリアル化されてxmlに保存されるテーブルを作成する「TableFactory」クラスがあります。このクラスでは、「ColumnDataTypes」列挙型と、許可したい型を処理するセクションを追加しました。現在、Integer、String、および File(byte[]) の 3 つだけです。この新しいアプローチの問題は、バイト配列を適切に格納するために、それを Base64String に変換する必要があることです。ただし、これによりデータ型がバイトではなく文字列に変更されるため、最初に戻ります...列データを解析し、それが単なる文字列ではなくバイト配列であることを論理的に判断するにはどうすればよいですか。バイト配列であることがわかったら、バイト配列を含むセルにボタンを配置できます。これを達成する方法について誰かアイデアがありますか?
テーブル ファクトリ クラス:
using System.Data;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using XML_Database.usrctrls;
namespace XML_Database.data
{
public class TableFactory
{
//string _tableName;
DataTable _dt;
//public string TableName { get { return _tableName; } set { _tableName = value; } }
public TableFactory(string tableName)
{
if (this._dt == null)
{
this._dt = new DataTable(tableName);
}
}
public DataTable Table
{
get { return this._dt; }
set { this._dt = value; }
}
public void NewColumn(string ColumnName, ColumnTypes colType)
{
if (!this._dt.Columns.Contains(ColumnName))
{
switch (colType)
{
case ColumnTypes.String:
this._dt.Columns.Add(ColumnName, typeof(String));
break;
case ColumnTypes.Integer:
this._dt.Columns.Add(ColumnName, typeof(Int32));
break;
case ColumnTypes.Binary:
this._dt.Columns.Add(ColumnName, typeof(Byte[]));
break;
}
}
}
public void DeleteColumn(string ColumnName)
{
if (_dt.Columns.Contains(ColumnName))
{
_dt.Columns.Remove(ColumnName);
}
}
public void SaveTable(string Path)
{
data.encryptFiles._SALT = data.dboptions.Salt();
data.encryptStrings._SALT = data.dboptions.Salt();
string tablePath = Path + "\\" + _dt.TableName + ".xml";
DataSet ds = new DataSet();
XmlDocument xDoc = new XmlDocument();
ds.Tables.Clear();
ds.Tables.Add(_dt.Copy());
XmlElement xE = (XmlElement)Serialize(ds);
string strXml = xE.OuterXml.ToString();
xDoc.LoadXml(strXml);
xDoc.Save(tablePath);
if (data.dboptions.DBEncryptionOptions())
{
File.Delete(Path + "\\" + _dt.TableName + "_enc.xml");
data.encryptFiles.EncryptFile(tablePath, tablePath.Replace(".xml", "_enc.xml"), data.encryptStrings.Decrypt(data.dboptions.Pwd(), data.dboptions.Salt()));
}
}
public void LoadTable(string Path)
{
string tablePath = Path + "\\" + _dt.TableName + ".xml";
XmlDocument xDoc = new XmlDocument();
if (File.Exists(tablePath))
{
if (_dt.TableName.Contains("_enc"))
{
MemoryStream ms = new MemoryStream();
data.encryptFiles._SALT = data.dboptions.Salt();
data.encryptStrings._SALT = data.dboptions.Salt();
data.encryptFiles.DecryptToMemory(tablePath, out ms, data.encryptStrings.Decrypt(data.dboptions.Pwd(), data.dboptions.Salt()));
using (ms)
{
xDoc.Load(ms);
}
DataSet ds = (DataSet)Deserialize(xDoc.DocumentElement, typeof(DataSet));
_dt = ds.Tables[0];
}
else
{
xDoc.Load(tablePath);
DataSet ds = (DataSet)Deserialize(xDoc.DocumentElement, typeof(DataSet));
_dt = ds.Tables[0];
}
}
}
private object Deserialize(XmlElement xmlElement, System.Type type)
{
Object transformedObject = null;
try
{
Stream memStream = StringToStream(xmlElement.OuterXml);
XmlSerializer serializer = new XmlSerializer(type);
transformedObject = serializer.Deserialize(memStream);
}
catch (Exception)
{
}
return transformedObject;
}
private Stream StringToStream(string p)
{
MemoryStream memStream = null;
try
{
byte[] buffer = Encoding.UTF8.GetBytes(p);
memStream = new MemoryStream(buffer);
}
catch (Exception)
{
}
finally
{
memStream.Position = 0;
}
return memStream;
}
private XmlElement Serialize(object TransformObject)
{
XmlElement serializedElement = null;
try
{
MemoryStream memStream = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(TransformObject.GetType());
serializer.Serialize(memStream, TransformObject);
memStream.Position = 0;
XmlDocument xDoc = new XmlDocument();
xDoc.Load(memStream);
serializedElement = xDoc.DocumentElement;
}
catch (Exception)
{
}
return serializedElement;
}
}
}
どんな助けでも大歓迎です!:)
編集: 画像は追加できますが、通常のファイルは追加できません。理想的には、ファイルと画像の両方を追加することが望ましい機能です。しかし、これまでのところ、Byte 配列の列に入るのは画像だけです。列のデータ型を文字列に変更し、変換されたBase64Stringを保存すればファイルを保存できますが、データを解析してテキストだけでなくファイルであることを確認する方法がまだわかりません...
編集:わかりました、この問題の解決に近づいていますが、こぶを乗り越える方法がわかりません...ボタンを表示することはできますが、正しいセルには表示されません。この質問に答えるのを手伝ってくれる人を助けるためのコードがいくつかあります...
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
button1.ForeColor = Color.Red;
try
{
for (int i = 0; i < dataGridView1.RowCount; i++)
{
foreach (DataGridViewCell cell in dataGridView1.Rows[i].Cells)
{
if (cell.Value != null)
{
if (TryParseBinary(cell.Value.ToString()))
{
var buttonCell = new DataGridViewButtonCell();
buttonCell.Value = "Export File";
buttonCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridView1.Rows[i].Cells[cell.ColumnIndex] = buttonCell;
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Grid Validation Error: " + ex.Message);
}
}
private bool TryParseBinary(string p)
{
try
{
string path = "C:\\Temp\\" + DateTime.Now.Ticks.ToString() + ".test";
byte[] bytes = Convert.FromBase64String(p);
File.WriteAllBytes(path, bytes);
//File.Delete(path);
return true;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
return false;
}
}
「TryParseBinary」が問題です。「true」を返すには有効なファイルを作成する必要がありますが、書き込んだばかりのファイルが有効なファイルであるかどうかを判断するのに十分なほどスマートにする方法がわかりません...