http://www.cnblogs.com/Charles2008/archive/2009/08/07/1541544.html
前段時間在開發一個關於RFID的winform程式, 其實關鍵還是winform項目(其實關於RFID的牽涉到很少),花了2個星期左右完成了。在項目的過程中隨便也回憶了關於winform的開發模式。平時一直都在做B/S的Asp.net,很少接觸winform的開發。(一些小的工具倒還是用winform來做).總的做下來,感覺最大的問題就是在前端表現起來很不容易控制,不像B/S結構那樣有JavaScript和CSS來實現。改一個javascript或CSS,整個系統的樣式都隨之更改。
總之不管怎樣,還是通過尋找以前實訓項目的代碼和在網上尋找相關的解決方案最終還是完成了。為了便於以後在做winform程式收集資源。現把相關的開發過程中一些細節知識點的解決方案記錄下來:
一、登入介面驗證成功後進入主介面,否則則退出應用程式。
假設登入表單frmLogin.cs和主介面frmMain.cs在程式的Main入口這樣來實現:
frmLogin login = new frmLogin();
login.ShowDialog();
if (frmLogin.blCanLogin == true)
{
Application.Run(new frmMain());
}
因此在frmLogin表單中增加一個靜態變數
public static bool blCanLogin = false;//記錄能否檢驗是否通
在登入事件中:
if(登入成功)
{
blCanLogin = true;
this.Close();
}
Else
{
..//to do
}
二、MDI父表單中彈出子表單
if (this.CheckChildFormExit("frmQuery") == true)
return;
else
{
frmQuery query = new frmQuery();
query.MdiParent = this;
query.Show();
}
//-----------------查詢一個子表單是否存在----------------
private bool CheckChildFormExit(string childFrmName)
{
foreach (Form childfrm in this.MdiChildren)
{
//用子表單的Name進行判斷,如果已經存在則將他啟用
if (childfrm.Name == childFrmName)
{
if (childfrm.WindowState == FormWindowState.Minimized)
childfrm.WindowState = FormWindowState.Normal;
childfrm.Activate();
return true;
}
}
return false;
}
三、設定DataGridView中行的背景顏色哦字型顏色(隔行變色)
在DataGridView的DataBindingComplete事件中實現:
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
this.dataGridView1.Rows[i].DefaultCellStyle.BackColor= System.Drawing.SystemColors.Info;//背景顏色
this.dataGridView1.Rows[i].DefaultCellStyle.ForeColor = System.Drawing.Color.Green;//字型顏色
this.dataGridView1.Rows[i].DefaultCellStyle.SelectionBackColor = System.Drawing.Color.Green;//選擇行的顏色
}
四、DataGridView控制項的列印
在網上找了一個DataGridView列印類,然後在它的基礎上進行了部門修改,以滿足項目的實際需要。
http://hi.baidu.com/bdhseaside/blog/item/f7db602443ed13054d088d02.html
五、日期時間的計算
在牽涉到查詢功能的時候需要顯示不同的日期:包括今天、本周、本月、本年、最近一周、最近本月、最近一月、最近一年
Code
/// 根據日期擷取當周星期一
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime StartOfTheWeek(DateTime dt)
{
return dt.AddDays(-(Convert.ToInt16(dt.DayOfWeek)-1));
}
/// <summary>
/// 根據日期擷取當周末
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime EndOfTheWeek(DateTime dt)
{
return StartOfTheWeek(dt).AddDays(6);
}
/// <summary>
///根據日期擷取月初日期
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime StartOfTheMonth(DateTime dt)
{
return new DateTime(dt.Year, dt.Month, 1);
}
/// <summary>
/// 根據日期擷取月底日期
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime EndOfTheMonth(DateTime dt)
{
return StartOfTheMonth(dt).AddMonths(1).AddDays(-1);
}
/// <summary>
/// 感覺日期年初日期
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime StartOfTheYear(DateTime dt)
{
return new DateTime(dt.Year, 1, 1);
}
/// <summary>
/// 根據日期擷取年底日期
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DateTime EndOfTheYear(DateTime dt)
{
return StartOfTheYear(dt).AddYears(1).AddDays(-1);
}
六、DataGridView幾個重要屬性
DataGridView.AutoGeneralColumn----¬是否自動產生列
DataGridView.ColumnHeadersVisible------指定是否顯示欄位標題行。
DataGridView.RowHeadersVisible-----指定是否顯示列名列。
DataGridView.SelectionMode-----知道DataGridView選擇儲存格的模式(儲存格,行)
DataGridView.AllowUserToResizeColumns----指定是否可以手動改變列的寬度。
DataGridView.AllowUserToResizeRows----指定是否可以手動改變行的高度。
七、DataGridView控制項匯出到Excel檔案
主要用了2種方式來實現:
1.格式不做限制,普通列表顯示:
/**//// <summary>
/// 常用方法,列之間加\t,一行一行輸出,此檔案其實是csv檔案,不過預設可以當成Excel開啟。
/// </summary>
/// <remarks>
/// using System.IO;
/// </remarks>
/// <param name="dgv"></param>
private void DataGridViewToExcel(DataGridView dgv)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.Filter = "Execl files (*.xls)|*.xls";
dlg.FilterIndex = 0;
dlg.RestoreDirectory = true;
dlg.CreatePrompt = true;
dlg.Title = "儲存為Excel檔案";
if (dlg.ShowDialog() == DialogResult.OK)
{
Stream myStream;
myStream = dlg.OpenFile();
StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding(-0));
string columnTitle = "";
try
{
//寫入欄位標題
for (int i = 0; i < dgv.ColumnCount; i++)
{
if (i > 0)
{
columnTitle += "\t";
}
columnTitle += dgv.Columns[i].HeaderText;
}
sw.WriteLine(columnTitle);
//寫入列內容
for (int j = 0; j < dgv.Rows.Count; j++)
{
string columnValue = "";
for (int k = 0; k < dgv.Columns.Count; k++)
{
if (k > 0)
{
columnValue += "\t";
}
if (dgv.Rows[j].Cells[k].Value == null)
columnValue += "";
else
columnValue += dgv.Rows[j].Cells[k].Value.ToString().Trim();
}
sw.WriteLine(columnValue);
}
sw.Close();
myStream.Close();
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
finally
{
sw.Close();
myStream.Close();
}
}
}
對於複雜的,對於匯出的excel有格式限制,可以考慮用Excel模板(XML支援)來實現。
Code
/// <summary>
/// 將DataGridView中的資料匯入到Excel中
/// </summary>
/// <param name="dt">DataGridView</param>
/// <param name="templatePath">模板的路徑</param>
/// <param name="excelName">匯入Excel的路徑</param>
/// <returns></returns>
public static bool DataGridViewToExcel(DataGridView dg, string templatePath, string excelName)
{
bool result = true;
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(templatePath))
{
xmlDoc.Load(templatePath);
XmlNode root = xmlDoc.SelectSingleNode(@"/*[local-name()='Workbook']/*[local-name()='Worksheet'][1]/*[local-name()='Table']");
foreach (DataGridViewRow dgRow in dg.Rows)
{
XmlElement row = xmlDoc.CreateElement("", "Row", "urn:schemas-microsoft-com:office:spreadsheet");
row.SetAttribute("AutoFitHeight", "urn:schemas-microsoft-com:office:spreadsheet", "0");
foreach (DataGridViewColumn dgcol in dg.Columns)
{
if (dgcol.Visible && dgcol.IsDataBound && dgcol.GetType().Name == "DataGridViewTextBoxColumn")
{
XmlElement cell = xmlDoc.CreateElement("", "Cell", "urn:schemas-microsoft-com:office:spreadsheet");
XmlElement data = xmlDoc.CreateElement("", "Data", "urn:schemas-microsoft-com:office:spreadsheet");
data.SetAttribute("Type", "urn:schemas-microsoft-com:office:spreadsheet", "String");
data.InnerText = StringUility.ReturnFormatString(dgRow.Cells[dgcol.Name].Value);
cell.AppendChild(data);
row.AppendChild(cell);
}
}
//root.InsertBefore(row, root.LastChild);
root.AppendChild(row);
}
#region 添加合計行
XmlElement totalRow = xmlDoc.CreateElement("", "Row", "urn:schemas-microsoft-com:office:spreadsheet");
totalRow.SetAttribute("AutoFitHeight", "urn:schemas-microsoft-com:office:spreadsheet", "0");
for (int i = 0; i < 2; i++)
{
XmlElement cell = xmlDoc.CreateElement("", "Cell", "urn:schemas-microsoft-com:office:spreadsheet");
XmlElement data = xmlDoc.CreateElement("", "Data", "urn:schemas-microsoft-com:office:spreadsheet");
data.SetAttribute("Type", "urn:schemas-microsoft-com:office:spreadsheet", i == 0 ? "String" : "Number");
data.InnerText =(i==0?"合計":dg.Rows.Count.ToString());
cell.AppendChild(data);
totalRow.AppendChild(cell);
}
root.AppendChild(totalRow);
#endregion
XmlNode countnode = xmlDoc.SelectSingleNode(@"/*[local-name()='Workbook']/*[local-name()='Worksheet'][1]/*[local-name()='Table']");
countnode.Attributes["ss:ExpandedRowCount"].Value = (Int32.Parse(countnode.Attributes["ss:ExpandedRowCount"].Value) + dg.Rows.Count+1).ToString();//標題+合計+資料
xmlDoc.Save(excelName);
result = true;
}
else
{
result = false;
}
return result;
}
另外還有通過Microsoft Excel 11.0(12) Object Library,使用using Excel=Microsoft.Office.Interop.Excel調用CoM來實現。但必須有要求是安裝該軟體的應用程式必須裝 Microsoft Office Excel才行。而且還應該設定運行該軟體的程式對COM有存取權限。
八、關於DataGridView控制項一些特殊設定可以參見:
使用DataGridView控制項常見問題集