I am creating a Windows Desktop XML database program for fun, and having trouble getting the data grid to recognize a binary string. It needs to determine if a string is binary data so that a button can appear in the cell where the binary data lives.
EDIT: Ok so I have decided that the easiest way to get to the desired result is to make the user choose the data type they wish to record. And then later check for that data type in each column and then place a button if that data type exists in a column.
I have a "TableFactory" class which makes the table that will be serialized and stored in xml. In this class I have added a "ColumnDataTypes" enum and a section to handle the types I want to allow, only 3 right now, Integer, String, and File(byte[]). The problem with this new approach is that in order to properly store the byte array I have to convert it to a Base64String. This however changes the data type to a string instead of a byte, so no button.
Table Factory Class:
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;
}
}
}
Any help is greatly appreciated! :)
I made the "DragDrop" method for my datagridview check for the existence of a "File" and "MIME" columns in the datatable. I then create those columns if they do not exist, if they do I add the file bytes converted to Base64String to the "File" column and the file extension to the "MIME" column. I then have the "RowsAdded" event change the "File" cells to buttons.
Below is what ended up working for me:
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
try
{
Point cursorPosition = dataGridView1.PointToClient(Cursor.Position);
DataGridView.HitTestInfo info = dataGridView1.HitTest(cursorPosition.X, cursorPosition.Y);
tableFactory = new data.TableFactory(TablesDropDown.SelectedValue.ToString());
tableFactory.LoadTable(dbPath);
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (DataColumn col in tableFactory.Table.Columns)
{
if (col.ColumnName != "MIME" && col.ColumnName != "File")
{
tableFactory.NewColumn("MIME", ColumnTypes.String);
tableFactory.NewColumn("File", ColumnTypes.String);
tableFactory.SaveTable(dbPath);
ColumnsDataGrid();
dataGridView1.Rows[info.RowIndex].Cells["File"].Value = Convert.ToBase64String(GetFile(files));
FileInfo f = new FileInfo(files[0]);
dataGridView1.Rows[info.RowIndex].Cells["MIME"].Value = f.Extension;
}
else
{
dataGridView1.Rows[info.RowIndex].Cells["File"].Value = Convert.ToBase64String(GetFile(files));
FileInfo f = new FileInfo(files[0]);
dataGridView1.Rows[info.RowIndex].Cells["MIME"].Value = f.Extension;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("This was not a valid file to store in the database. Error Msg: " + ex.Message);
}
}
private byte[] GetFile(string[] files)
{
byte[] bytes = null;
foreach (string file in files)
{
FileInfo fileInfo = new FileInfo(file);
if (File.Exists(file))
{
bytes = File.ReadAllBytes(file);
}
}
return bytes;
}
private void dataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
button1.ForeColor = Color.Red;
try
{
for (int i = 0; i < dataGridView1.RowCount; i++)
{
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
if (col.Name == "File")
{
var buttonCell = new DataGridViewButtonCell();
buttonCell.Value = "Export File";
buttonCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridView1.Rows[i].Cells[col.Index] = buttonCell;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Grid Validation Error: " + ex.Message);
}
}