2010年10月30日 星期六

DataGridView 的連結顯示以及連結網址設定

近用到 windows form 內的 DataGridView 控制項,裡面有一欄位型態 DataGridViewLinkColumn,用來連結或處理資料之用,但是用的時候,設定欄位 Text 為「連結網址」,執行後,卻無字樣。例如以下所示:
程式碼:
private void Form1_Load(object sender, EventArgs e)
{
((DataGridViewLinkColumn)dataGridView1.Columns["gvRGoogleLink"]).Text = "連結網頁";
dataGridView1.Rows.Add("C語言", "");
dataGridView1.Rows.Add("程式設計筆記", "");
}
執行後截圖:上圖所示,在 Google Link 欄位並無連結字樣。但是加上
((DataGridViewLinkColumn)dataGridView1.Columns["gvRGoogleLink"]).UseColumnTextForLinkValue = true;
這行程式碼,即可將連結字樣顯示。
加入此行程式碼執行後截圖:連結字樣就會出現了,接下來就是設定連結的事件。
而連結事件所要利用到 CellClick 事件,當點擊某一欄位時,觸發 CellClick 事件,將此行 Keywoed 轉換編碼導向 Google 搜尋頁面。
程式碼如下:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
/* 確認欄位型態 */
if (dataGridView1.Columns[e.ColumnIndex] is DataGridViewLinkColumn)
{
/* 確認欄位名稱 */
switch (dataGridView1.Columns[e.ColumnIndex].Name)
{
case "gvRGoogleLink": /* 觸發事件 */
string keyword = Convert.ToString(dataGridView1.Rows[e.RowIndex].Cells["gvRKeyword"].Value);
string encKeyword = encKeyword = System.Web.HttpUtility.UrlEncode(keyword);

string url = string.Format("http://www.google.com.tw/search?q={0}", encKeyword);
System.Diagnostics.Process.Start(url);
break;
}
}
}


回目錄
回首頁

2010年10月28日 星期四

利用 XElement 類別擷取 IP 所在之國家 ( Country )

引用網址:http://byteblocks.com/post/2009/06/01/Convert-IP-To-Location-and-Address-To-Location.aspx

首先,利用 WebClient 類別下載網頁原始碼那是必需的,但最重要的是要有網頁能提供 IP 查詢國家所在,所以找到了 http://ipinfodb.com/ip_query.php 這網頁,此網頁不吃參數時,預設會找出你電腦 IP 的相關資料( 包含電腦所在國家 ),但若吃 ip 參數時,就會列出此 ip 相關參數,例如:
http://ipinfodb.com/ip_query.php?ip=61.219.38.89
此 ip 為中華電信之 IP。

所以若要以 IP 找出相關資料,可利用以下程式擷取出來。
static void Main(string[] args)
{
string Ip = "61.219.38.89"; /* 中華電信 IP */
string Url = string.Format("http://ipinfodb.com/ip_query.php?ip={0}", Ip);
string Content = GetUrlContent(Url);

StringReader sr = new StringReader(Content);
XElement xe = XElement.Load(sr);
string strStatus = Convert.ToString(xe.Element("Status").Value);

if (string.Compare(strStatus, "OK", true) == 0)
{
Console.WriteLine(Convert.ToString(xe.Element("CountryName").Value));
}
}

static string GetUrlContent(string Url)
{
string content = string.Empty;
WebClient client = new WebClient();
try
{
content = client.DownloadString(Url);
}
catch (WebException we)
{
content = we.Message;
}
return content;
}
最後,只要依據 IP 的不同,就能擷取出 IP 的相關資料。

回目錄
回首頁

2010年10月12日 星期二

Repeater 取得 Header 區控制項

Repeater 控制項中,不像 RadGrid 有 .MasterTableView.GetItems 方法可以使用,此時就需要將 Repeater 內的所有控制項全部掃過一次,在找出屬於 Header 區的控制項。

例如要找出位於 Header 區中 ID 為 control_1 的 Label 控制項,將它的屬性 Text 改為字串 HaHa。
以下為 *.aspx 內範例程式碼:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<asp:Label ID="control_1" runat="server"></asp:Label>
</HeaderTemplate>
</asp:Repeater>

接著要在 *.cs 內 寫入以下程式:
foreach (Control c in Repeater1.Controls)
{
RepeaterItem item = (RepeaterItem)c;
if (item.ItemType == ListItemType.Header)
{
Label headerItem = (Label)item.FindControl("control_1");
headerItem.Text = "HaHa";

}
}


回目錄
回首頁

2010年10月8日 星期五

兩段時間 ( DateTime ) 的時間差

在做日期相減時,可以使用 DateTime 設定兩段欲相減的時間,再使用 TimeSpan 算出兩段時間的間隔,總共是多少天數( Day )、多少小時( Hour )、多少毫秒( TotalMillisecond )、多少分鐘( Minute )抑或是多少秒( Second )。

以下例子就是以現在的時間,距離 2010 年 1 月 1 日 0 時 0 分 0 秒的時間差。
DateTime dt = DateTime.Now;
DateTime _dt = new DateTime(2010, 1, 1, 0, 0, 0);
TimeSpan ts = dt.Subtract(_dt);
Console.WriteLine(ts.TotalDays + " Days.");
Console.WriteLine(ts.TotalHours + " Hours.");
Console.WriteLine(ts.TotalMilliseconds + " Milliseconds");
Console.WriteLine(ts.TotalMinutes + " Minutes");
Console.WriteLine(ts.TotalSeconds + " Seconds");


回目錄
回首頁

2010年10月7日 星期四

RSS Reader

可以在 http://www.geekpedia.com/tutorial147_Creating-an-RSS-feed-reader-in-Csharp.html 下載到 vs 2005 winForm 寫的 RSS 讀取器,但只能讀取特定格式的 RSS。

以下為此檔案的程式碼內容,核心部份會用紅色標起來。
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;

namespace RSS_Reader
{
public partial class frmMain : Form
{
XmlTextReader rssReader;
XmlDocument rssDoc;
XmlNode nodeRss;
XmlNode nodeChannel;
XmlNode nodeItem;
ListViewItem rowNews;

public frmMain()
{
InitializeComponent();
}

private void btnRead_Click(object sender, EventArgs e)
{
lstNews.Items.Clear();
this.Cursor = Cursors.WaitCursor;
// Create a new XmlTextReader from the specified URL (RSS feed)
rssReader = new XmlTextReader(txtUrl.Text);
rssDoc = new XmlDocument();
// Load the XML content into a XmlDocument
rssDoc.Load(rssReader);

// Loop for the <rss> tag
for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
{
// If it is the rss tag
if (rssDoc.ChildNodes[i].Name == "rss")
{
// <rss> tag found
nodeRss = rssDoc.ChildNodes[i];
}
}

// Loop for the <channel> tag
for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
{
// If it is the channel tag
if (nodeRss.ChildNodes[i].Name == "channel")
{
// <channel> tag found
nodeChannel = nodeRss.ChildNodes[i];
}
}


// Set the labels with information from inside the nodes
lblTitle.Text = "Title: " + nodeChannel["title"].InnerText;
lblLanguage.Text = "Language: " + nodeChannel["language"].InnerText;
lblLink.Text = "Link: " + nodeChannel["link"].InnerText;
lblDescription.Text = "Description: " + nodeChannel["description"].InnerText;

// Loop for the <title>, <link>, <description> and all the other tags
for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
// If it is the item tag, then it has children tags which we will add as items to the ListView
if (nodeChannel.ChildNodes[i].Name == "item")
{
nodeItem = nodeChannel.ChildNodes[i];


// Create a new row in the ListView containing information from inside the nodes
rowNews = new ListViewItem();
rowNews.Text = nodeItem["title"].InnerText;
rowNews.SubItems.Add(nodeItem["link"].InnerText);
lstNews.Items.Add(rowNews);
}
}


this.Cursor = Cursors.Default;
}

private void lstNews_SelectedIndexChanged(object sender, EventArgs e)
{
// When an items is selected
if (lstNews.SelectedItems.Count == 1)
{
// Loop through all the nodes under <channel>
for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
// Until you find the lt;itemgt; node
if (nodeChannel.ChildNodes[i].Name == "item")
{
// Store the item as a node
nodeItem = nodeChannel.ChildNodes[i];
// If the <title> tag matches the current selected item
if (nodeItem["title"].InnerText == lstNews.SelectedItems[0].Text)
{
// It's the item we were looking for, get the description
txtContent.Text = nodeItem["description"].InnerText;
// We don't need to loop anymore
break;
}
}
}
}
}

private void lstNews_DoubleClick(object sender, EventArgs e)
{
// When double clicked open the web page
System.Diagnostics.Process.Start(lstNews.SelectedItems[0].SubItems[1].Text);
}
}
}


回目錄
回首頁

2010年10月6日 星期三

Ini 檔案的讀取與寫入類別

Ini 檔案又稱設定檔,無固定格式,僅以簡單的結構與文字組成,許多程式都會將它當作初始化之檔案。
此篇文章提供程式碼中,可以將 key 和 value 寫到同一個 section,或者將某一個 section 指定 key 的 value 讀出,又或者可以將某個 section 讀出,而我參考 http://www.codeproject.com/KB/cs/cs_ini.aspx 後,寫成以下類別,方便大家引用。
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;

namespace Ini
{
public class IniFile
{
public string path;

[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,
string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section,
string key, string def, StringBuilder retVal,
int size, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileSection(string section, IntPtr lpReturnedString,
int nSize, string lpFileName);

// INIPath 為檔案路徑,isDel 為是否覆蓋原檔
public IniFile(string INIPath, bool isDel)
{
if (!isDel)
{
if (!File.Exists(INIPath))
File.Create(INIPath);
}
else
{
FileStream fs = new FileStream(INIPath, FileMode.Create);
fs.Close();
}
this.path = INIPath;
}

// 寫入指定 Section,指定 Key,指定 Value。
public void IniWriteValue(string Section, string Key, string Value)
{
WritePrivateProfileString(Section, Key, Value, this.path);
}

// 讀取指定 Section,指定 Key 的 Value。
public string IniReadValue(string Section, string Key)
{
StringBuilder temp = new StringBuilder(255);
int i = GetPrivateProfileString(Section, Key, "", temp,
255, this.path);
return temp.ToString();

}

// 讀取指定 Section 所有的 Value。
public string[] ReadSection(string section)
{
const int bufferSize = 2048;

StringBuilder returnedString = new StringBuilder();

IntPtr pReturnedString = Marshal.AllocCoTaskMem(bufferSize);
try
{
int bytesReturned = GetPrivateProfileSection(section, pReturnedString, bufferSize, path);

//bytesReturned -1 to remove trailing \0
for (int i = 0; i < bytesReturned - 1; i++)
returnedString.Append((char)Marshal.ReadByte(new IntPtr((uint)pReturnedString + (uint)i)));
}
finally
{
Marshal.FreeCoTaskMem(pReturnedString);
}

string sectionData = returnedString.ToString();
return sectionData.Split('\0');
}
}
}


回目錄
回首頁

利用 gmail 寄信

以下程式碼可以使 DavidKuo's Mail 寄信給 A's Mail,信件標題為 subject,內文為 body。

要匯入 System.Net 和 System.Net.Mail 兩套件。
string fromEmail = "DavidKuo'sMail@gmail.com"; // 寄信人
string fromName = "DavidKuo"; // 寄信人姓名

MailAddress from = new MailAddress(fromEmail, fromName, Encoding.UTF8);

string toEmail = "A'sMail@gmail.com"; // 收信人

MailMessage mail = new MailMessage(from, new MailAddress(toEmail));

string subject = "subject";
mail.Subject = subject;
mail.SubjectEncoding = Encoding.UTF8;

string body = "body";
mail.Body = body;
mail.BodyEncoding = Encoding.UTF8;
mail.IsBodyHtml = false; // 是否為 Html 格式
mail.Priority = MailPriority.High; // 信件優先權

SmtpClient client = new SmtpClient();
client.Host = "smtp.gmail.com";
client.Port = 587;
client.Credentials = new NetworkCredential("DavidKuo'sMail@gmail.com", "DavidKuo'sMailPassword");
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;

client.Send(mail); // 寄信


參考網址:http://www.dotblogs.com.tw/chhuang/archive/2008/03/18/1815.aspx

回目錄
回首頁

2010年10月5日 星期二

清空資料 ClearTextBox()

在按下送出鍵後, 需要清空TextBox內容,
(1)方法, 要一個一個對欄位增加。
(2)方法, 是只要下ClearTexBox(), 就可以清空所有欄位的內容。

(1)
TextBox1.Text = ""
(2)

Private Sub ClearTextBox()
For Each control As System.Web.UI.Control In Me.Controls
For i As Integer = 0 To control.Controls.Count - 1
If TypeOf control.Controls(i) Is System.Web.UI.WebControls.TextBox Then
Dim tbx As System.Web.UI.WebControls.TextBox = DirectCast(control.Controls(i), System.Web.UI.WebControls.TextBox)
tbx.Text = ""
End If
Next
Next
End Sub

回目錄
回首頁

2010年10月3日 星期日

使用 FolderBrowserDialog 決定資料夾路徑

上次取得檔案路徑,此篇文章將提供取得資料夾路徑之程式碼,

FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.Description = "Please select one folder";

fbd.ShowNewFolderButton = false;
// fbd.RootFolder = Environment.SpecialFolder.MyDocuments;

if (fbd.ShowDialog() == DialogResult.Cancel)
return;
textBox1.Text = fbd.SelectedPath;


以上程式碼之中,並沒有明訂根目錄位置,如果未定義,桌面即為根目錄。
還有以下幾種設定:
  1. Environment.SpecialFolder.ApplicationData
    表示做為目前漫遊使用者的應用程式特定資料之通用儲存機制的目錄。
  2. Environment.SpecialFolder.CommonApplicationData
    表示做為所有使用者使用的應用程式特定資料之通用儲存機制的目錄。
  3. Environment.SpecialFolder.LocalApplicationData
    表示做為目前非漫遊使用者使用的應用程式特定資料之通用儲存機制的目錄。
  4. Environment.SpecialFolder.Cookies
    表示做為網際網路 Cookie 通用儲存機制的目錄。
  5. Environment.SpecialFolder.Desktop
    邏輯的 [桌面],而不是實體的檔案系統位置。
  6. Environment.SpecialFolder.Favorites
    表示做為使用者的我的最愛項目之通用儲存機制的目錄。
  7. Environment.SpecialFolder.History
    表示做為網際網路記錄項目通用儲存機制的目錄。
  8. Environment.SpecialFolder.InternetCache
    表示做為網際網路暫存檔通用儲存機制的目錄。
  9. Environment.SpecialFolder.Programs
    包含使用者程式群組的目錄。
  10. Environment.SpecialFolder.MyComputer
    [我的電腦] 資料夾。
  11. Environment.SpecialFolder.MyMusic
    [我的音樂] 資料夾。
  12. Environment.SpecialFolder.MyPictures
    [我的圖片] 資料夾。
  13. Environment.SpecialFolder.Recent
    包含使用者最近使用之文件的目錄。
  14. Environment.SpecialFolder.SendTo
    包含 [傳送到] 功能表項目的目錄。
  15. Environment.SpecialFolder.StartMenu
    包含 [開始] 功能表項目的目錄。
  16. Environment.SpecialFolder.Startup
    對應至使用者 [啟動] 程式群組的目錄。
  17. Environment.SpecialFolder.System
    System 目錄。
  18. Environment.SpecialFolder.Templates
    表示做為文件樣板 (Template) 通用儲存機制的目錄。
  19. Environment.SpecialFolder.DesktopDirectory
    表示用來實際儲存桌面上檔案物件的目錄。
  20. Environment.SpecialFolder.Personal
    表示做為文件通用儲存機制的目錄。
  21. Environment.SpecialFolder.MyDocuments
    [我的文件] 資料夾。
  22. Environment.SpecialFolder.ProgramFiles
    Program Files 目錄。
  23. Environment.SpecialFolder.CommonProgramFiles
    表示在應用程式間共享的元件的目錄。


參考網址:Environment.SpecialFolder 列舉型別

回目錄
回首頁

2010年10月1日 星期五

DateTime 取得常用時間

引用網址:http://www.cnblogs.com/sekihin/archive/2008/03/27/1124446.html
以上引用網址為 VB 語法,以下提供 C# 語法。
DateTime Now = DateTime.Now; // 當前時間。
DateTime StartWeek =
Now.AddDays(1 - Convert.ToInt32(Now.DayOfWeek.ToString("d"))); // 禮拜一日期
DateTime EndWeek = StartWeek.AddDays(6); // 禮拜日日期
DateTime StartMonth = Now.AddDays(1 - Now.Day); // 月初
DateTime EndMonth = StartMonth.AddMonths(1).AddDays(-1); // 月末

DateTime StartQuarter = Now.AddMonths(0 - (Now.Month - 1) % 3).AddDays(1 - Now.Day); // 本季初
DateTime EndQuarter = StartQuarter.AddMonths(3).AddDays(-1); // 本季末
DateTime StartYear = new DateTime(Now.Year, 1, 1); // 年初
DateTime EndYear = new DateTime(Now.Year, 12, 31); // 年末


回目錄
回首頁