I've got a DataGridView using a DataTable as it's DataSource. I'm allowing the user to alter the visibility, order (and width though that's not relevant to this question) of the DataGridView columns, but not the underlying DataTable. This means I don't have to recreate the DataTable every time the user makes a change to the view.
The user can export the DataTable to an XML file and I'd like the output to reflect what's on the screen. I originally had the following:
dataTable.WriteXml(saveFileDialog.FileName, XmlWriteMode.WriteSchema);
But this (obviously) writes all of the columns in the DataTable to file including the invisible ones in the order they're defined.
I've got the following code in the export button handler method. I know that it's in the wrong place, but I'm stumped as it needs to reference the DataGridView.
private void export_Click(object sender, EventArgs e)
{
// Show the SaveFileDialog.
var saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = Properties.Resources.TSaveLibrary;
saveFileDialog.Filter = Properties.Resources.TXMLFilter;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
using (XmlWriter writer = XmlWriter.Create(saveFileDialog.FileName))
{
writer.WriteStartDocument();
writer.WriteRaw("\n");
writer.WriteStartElement("Library");
writer.WriteRaw("\n");
// Find the visible columns and put them in display order
var dcCollection = new List<string>();
DataGridViewColumn dc = dataGridView.Columns.GetFirstColumn(DataGridViewElementStates.Visible);
while (dc != null)
{
if (dc.Visible)
{
dcCollection.Add(dc.Name);
}
dc = dataGridView.Columns.GetNextColumn(dc, DataGridViewElementStates.Visible, DataGridViewElementStates.None);
}
// Write the data
foreach (DataRow dr in dataTable.Rows)
{
writer.WriteRaw(" ");
writer.WriteStartElement(dataTable.TableName);
writer.WriteRaw("\n");
foreach (string colName in dcCollection)
{
writer.WriteRaw(" ");
writer.WriteElementString(colName, dr[colName].ToString());
writer.WriteRaw("\n");
}
writer.WriteRaw(" ");
writer.WriteEndElement();
writer.WriteRaw("\n");
}
writer.WriteEndElement();
writer.WriteRaw("\n");
writer.WriteEndDocument();
}
}
}
Any suggestions on how I can refactor this code?