2008/05/30

Windows Form: Control the Closing icon ("X" button)

If you set the control box property to true (Fig.1), the UI will then show the control box which contains MinimizeBox, MaximizeBox, and the "X" button.
Fig.1
The "X" button usually means close/exit this windows form (or application). Can we have more control of this behavior (or the "X" button)?

Yes, we can. In your code behind, create an event for the form you want to control like this:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  DialogResult dr = MessageBox.Show("Do you really want to leave?", "Confirm Window", MessageBoxButtons.YesNoCancel);

  if (dr == DialogResult.No || dr == DialogResult.Cancel)
  {
    MessageBox.Show("That's my boy~");
    e.Cancel = true; //means cancel this event
  }
  else
    MessageBox.Show("Bad boy!");
}

Every time when user clicks on the "X" button to close the form, it will trigger the above event and perform whatever you design in there.

2008/05/16

Use XmlDocument to generate XML

This way is much simpler than XmlTextWriter:
public static String createItem(DataTable dt)
{
  XmlDocument XmlDoc = new XmlDocument();
  XmlDoc.LoadXml("");
  XmlElement XmlElem;

  foreach (DataRow dr in dt.Rows)
  {
    XmlElem = XmlDoc.CreateElement("customer");
    XmlElem.SetAttribute("Name", dr["custName"].ToString());
    XmlElem.SetAttribute("ID", dr["custID"].ToString());
    XmlElem.SetAttribute("Address", dr["address"].ToString());
    XmlElem.SetAttribute("ZipCode", dr["zip"].ToString());
    XmlElem.SetAttribute("Phone", dr["phone"].ToString());
    XmlElem.InnerText = "Kenny";

    XmlDoc.DocumentElement.AppendChild(XmlElem);
  }

  return XmlDoc.FirstChild.InnerXml;
}

Use XmlTextWriter to generate XML

using (MemoryStream ms = new MemoryStream())
{
  XmlTextWriter Xwriter = new XmlTextWriter(ms, Encoding.UTF8);

  Xwriter.WriteStartDocument();  //Put the XML declaration
  Xwriter.Formatting = Formatting.Indented;  //Format the XML document

  Xwriter.WriteComment("XML sample file for ch2.2"); //Put a comment
  Xwriter.WriteStartElement("po");  //This is the root element
  Xwriter.WriteAttributeString("id", "PO1456");

  Xwriter.WriteStartElement("address");
  Xwriter.WriteAttributeString("type", "shipping");
  Xwriter.WriteElementString("name", "Frits Mendels");
  Xwriter.WriteElementString("street", "152 Cherry St");
  Xwriter.WriteElementString("city", "San Francisco");
  Xwriter.WriteElementString("state", "CA");
  Xwriter.WriteElementString("zip", "94045");
  Xwriter.WriteEndElement();

  Xwriter.WriteStartElement("items");
  Xwriter.WriteStartElement("item");
  Xwriter.WriteAttributeString("quantity", "1");
  Xwriter.WriteAttributeString("productCode", "R-273");
  Xwriter.WriteAttributeString("description", "14.4 Volt Cordless Drill");
  Xwriter.WriteAttributeString("unitCost", "189.95");
  Xwriter.WriteEndElement();

  Xwriter.WriteStartElement("item");
  Xwriter.WriteAttributeString("quantity", "1");
  Xwriter.WriteAttributeString("productCode", "1632S");
  Xwriter.WriteAttributeString("description", "12 Piece Drill Bit Set");
  Xwriter.WriteAttributeString("unitCost", "14.95");
  Xwriter.WriteEndElement();
  Xwriter.WriteEndElement();

  Xwriter.WriteEndElement();
  Xwriter.WriteEndDocument();
  Xwriter.Flush();  //flush everything from the buffer
  ms.Position = 0;
  StreamReader sr = new StreamReader(ms);
  return sr.ReadToEnd();
}

The output will be



Frits Mendels 152 Cherry St San Francisco CA 94045

We can also use StreamWriter class instead of MemoryStream, just replace this line of code
XmlTextWriter Xwriter = new XmlTextWriter(ms, Encoding.UTF8);
with
StreamWriter sw = new StreamWriter();
XmlTextWriter Xwriter = new XmlTextWriter(sw);
and remove the using of MemoryStream. Also replace this part
Xwriter.Flush();
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
return sr.ReadToEnd();
with
Xwriter.Flush();
Xwriter.Close();
return sw;

Here is an example from Microsoft Technet.