- 示範資料
星期二, 9月 30, 2014
星期一, 9月 29, 2014
[C#] PictureBox 顯示圖片
練習根據 DataGridView 上的圖片路徑紀錄,在 PictureBox 上顯示圖片
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
getData();
}
private void getData()
{
DataTable dt = new DataTable("Demo");
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Path", typeof(string));
dt.Rows.Add(1, @"D:\Image01.JPG");
dt.Rows.Add(2, @"D:\Image02.JPG");
dt.Rows.Add(3, @"D:\Image03.JPG");
dt.Rows.Add(4, @"D:\Image04.JPG");
dt.Rows.Add(5, @"D:\Image05.JPG");
dt.Constraints.Add("PK", dt.Columns["ID"], true);
dgvData.DataSource = dt;
dgvData.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
// Code 寫在 SelectionChanged 內才可以用滑鼠或鍵盤根據資料變化圖片
private void dgvData_SelectionChanged(object sender, EventArgs e)
{
string path = dgvData.Rows[dgvData.CurrentCell.RowIndex].Cells["Path"].Value.ToString();
if (!File.Exists(path)) return;
Bitmap Image = new Bitmap(path);
pbImage.Image = Image;
}
}
}
星期五, 9月 26, 2014
[SQL] Linked Server 抓取 Text 檔案
紀錄要如何利用 Linked Server 抓取 Text 檔案內資料
- Linked Server
-- 檢查 Linked Server 是否存在
IF EXISTS
(
SELECT 1
FROM sys.servers s
INNER JOIN sys.linked_logins l ON s.server_id = l.server_id
WHERE s.is_linked = 1
AND name = 'txtDemo'
)
EXEC master.sys.sp_dropserver 'txtDemo', 'droplogins'
GO
-- 建立 Linked Server
EXEC master.dbo.sp_addlinkedserver
@server = N'txtDemo', -- 檔案名稱
@srvproduct=N'SQLSERVER',
@provider=N'Microsoft.ACE.OLEDB.12.0',
@datasrc=N'D:\', -- 檔案所在路徑
@location= NULL,
@provstr= N'Text',
@catalog = NULL
GO
-- 抓取 Text 檔案資料
SELECT * FROM txtDemo...demo#txt
- OpenRowSet
SELECT *
FROM OPENROWSET
(
'Microsoft.ACE.OLEDB.12.0',
'Text;Database=D:\;HDR=YES;Format=Delimited(,)',
'SELECT * FROM [demo.txt]'
)
星期四, 9月 25, 2014
[Excel] 選取全部資料
以往要選取 Excel 內的資料,都是利用滑鼠從最後一筆資料的最後一個欄位往上選取,但資料量很龐大,光是要利用捲軸找到最後一筆資料就很麻煩,還常常拉過頭,Orz ~~
其實 Excel 內有快速鍵可以使用, Ctrl + Shift + 方向鍵選取資料(以最左上角為起點的話,方向鍵右 + 方向鍵下或方向鍵下 + 方向鍵右),就可以快速選取全部資料
其實 Excel 內有快速鍵可以使用, Ctrl + Shift + 方向鍵選取資料(以最左上角為起點的話,方向鍵右 + 方向鍵下或方向鍵下 + 方向鍵右),就可以快速選取全部資料
星期三, 9月 24, 2014
[C#] Structs VS Classes
MVA Twenty C# Questions Explained - [01 Structs VS Classes],聽完後順道找些資料來了解並整理記錄成筆記
Structs 和 Classes 的比較
MSDN Structs 限制
Structs 和 Classes 的比較
Structs | Classes |
---|---|
Value type | Refrence type |
記憶體中為 stack | 記憶體中為 heap |
不支援 null | 支援 null |
MSDN Structs 限制
- 結構宣告內不能初始化欄位,除非將其宣告為 const 或 static。
- 結構不可宣告預設建構函式 (沒有參數的建構函式) 或解構函式。
- 結構是在指派時複製的。 當指派結構給新變數時,就會複製所有資料,而新變數所做的任何修改都不會變更原始複本的資料。 在使用如 Dictionary 的實際型別集合時,請務必謹記這一點。
- 結構為實值型別,而類別則是參考型別。
- 與類別不同的是,結構並不需要使用 new 運算子就能具現化。
- 結構可以宣告含有參數的建構函式。
- 結構無法從另一個結構或類別繼承而來,且它不能成為類別的基底。 所有結構都是從繼承自 System.Object 的 System.ValueType 直接繼承而來
- 結構可實作介面
- 結構可以用來當做可為 Null 的型別,而且可以對其指派 null 值。
星期二, 9月 23, 2014
[LINQ] 累計加總
之前是利用 T-SQL 作到,這次是用 LINQ 來練習
namespace LINQRunningTotal
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int LINQQty = 0;
var LINQSource = (from data in getData().AsEnumerable()
orderby data.Field<int>("Qty") descending
select new
{
Question = data.Field<string>("Question"),
Qty = data.Field<int>("Qty"),
RuningTotal = (LINQQty += data.Field<int>("Qty"))
}).ToList();
int LamdbaQty = 0;
var LamdbaSource = getData().AsEnumerable().
OrderByDescending(data => data.Field<int>("Qty")).
Select
(data =>
{
LamdbaQty += data.Field<int>("Qty");
return new
{
Question = data.Field<string>("Question"),
Qty = data.Field<int>("Qty"),
RunningTotal = LamdbaQty
};
}
).ToList();
dgvData.DataSource = LamdbaSource;
}
private DataTable getData()
{
DataTable dt = new DataTable("ParetoChart");
dt.Columns.Add("Question", typeof(string));
dt.Columns.Add("Qty", typeof(int));
dt.Columns.Add("RunningTotal", typeof(int));
dt.Rows.Add("馬達運轉異常", 38, 0);
dt.Rows.Add("馬達異音", 22, 0);
dt.Rows.Add("運輸撞傷", 6, 0);
dt.Rows.Add("鰭片間距不良", 0, 0);
dt.Rows.Add("銅管凹陷", 2, 0);
dt.Rows.Add("組裝不良", 17, 0);
dt.Rows.Add("洩漏", 3, 0);
return dt;
}
}
}
- 參考資料
- stackoverflow 討論
星期一, 9月 22, 2014
[C#] ListBox 基本操作
整理 ListBox 的基本操作
namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // 建立 ListBox 內的資料來源 lstData.Items.Add("111"); lstData.Items.Add("222"); lstData.Items.Add("333"); lstData.Items.Add("444"); lstData.Items.Add("555"); } private void btnAdd_Click(object sender, EventArgs e) { string content = txtContent.Text.Trim(); if (string.IsNullOrEmpty(content)) return ; lstData.Items.Add(content); } private void btnTruncate_Click(object sender, EventArgs e) { lstData.Items.Clear(); } private void btnModify_Click(object sender, EventArgs e) { string NewData = txtContent.Text.Trim(); if (string.IsNullOrEmpty(NewData)) return; int index = lstData.SelectedIndex; if (index == -1) return; lstData.Items[index] = NewData; } private void btnDelete_Click(object sender, EventArgs e) { int index = lstData.SelectedIndex; if (index == -1) return; lstData.Items.RemoveAt(index); } private void btnSearch_Click(object sender, EventArgs e) { if (lstData.Items.Count == 0) return; string search = txtSearch.Text.Trim(); if (string.IsNullOrEmpty(search)) return; int index = lstData.FindStringExact(search); if (index == -1) { MessageBox.Show("ListBox 內沒有該項目"); } else { lstData.SelectedIndex = index; } } } }
- 參考資料
- [C#]ListBox如何偵測Item的新增、插入、與刪除
- ListBox.FindStringExact 方法
- C# ListBox-假如 DataSource 是 List 的話,沒有辦法對 Lsit.Items 進行新增、修改和刪除,必須直接對 List 進行,之後再重新 DataBind
星期五, 9月 19, 2014
星期三, 9月 17, 2014
[C#] Console 應用程式路徑
MVA Twenty C# Questions Explained - [04 How do I get the application's path in a C# console app?]
Console 路徑
Console 路徑
namespace MVATwentyQuestions { class Program { static void Main(string[] args) { // 利用 Reflection 來進行 string ConsolePath = System.Reflection.Assembly.GetExecutingAssembly().Location; Console.WriteLine(System.IO.Path.GetDirectoryName(ConsolePath)); } } }Winform 路徑
private void btnPath_Click(object sender, EventArgs e) { string WinformPath = Application.StartupPath; MessageBox.Show(WinformPath); }
星期二, 9月 16, 2014
[C#] Interface
此論壇問題練習是根據前輩提供給原 PO 的建議
如果您是寫win form可以寫以下功能:form1、form2 都可以開啟 form3,form1 有text box、form2 有combo box,請寫出 form3 button click 後可以取得開始自己的那個表單裡控制項的值
- 建立 IDemo Interface 並建立 showData Method
namespace WindowsFormsApplication1
{
public interface IDemo
{
string showData();
}
}
星期一, 9月 15, 2014
[C#] 格式化日期資料
拿論壇問題來練習一下
在 GridView 控件上設定完成後,可以在 .aspx 內看見 DataFormatString 設定值
資料在 MS SQL 內是利用 date 資料型態 儲存,但是在 DataGridView 上卻連時間都顯示出來,EX:MS SQL => 2014/08/24、GrdView => 2014/08/24 2014/8/26 上午 12:00:00,要如何在 DataGridView 只顯示 2014/08/24
- 直接在控件上設定 DataFormatString
在 GridView 控件上設定完成後,可以在 .aspx 內看見 DataFormatString 設定值
- 利用 Code 設定 DataFormatString
using System.Data; using System.Data.SqlClient; namespace DateFormat { public partial class Demo : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { string connString = @"Data Source=Win7\SQL2012;Initial Catalog=AdventureWorks2012;Integrated Security=True"; using (SqlConnection conn = new SqlConnection(connString)) { string TSQL = "SELECT Data AS Data1 , Data AS Data2 FROM dbo.Demo"; SqlDataAdapter da = new SqlDataAdapter(TSQL, connString); DataTable dt = new DataTable("Demo"); da.Fill(dt); // 設定 DataFormatString BoundField colFormat = GridView1.Columns[1] as BoundField; colFormat.DataFormatString = "{0:yyyy/MM/dd}"; GridView1.DataSource = dt; GridView1.DataBind(); } } } } }
- 參考資料
- 論壇問題
星期三, 9月 10, 2014
[C#] 呼叫父建構子
MVA Twenty C# Questions Explained - [05 How do you call a base constructor in C#?]
Demo1 結果
Demo2 結果
namespace MVATwentyQuestions
{
class Test
{
// 故意用 public 來方便 demo,實務上應該設為 private
public string _name = "";
public Test(string name)
{
_name = name;
}
public virtual void ConvertToUpper()
{
_name = _name.ToUpper();
}
}
}
namespace MVATwentyQuestions
{
class InheritTest : Test
{
// 錯誤的呼叫方式
// base("NewName");
// Demo1 和 Demo2 只能存在一個,請自行轉換 comment 來觀察結果
// demo1:正確呼叫 base 的方式
public InheritTest(string name): base(name)
{
}
// demo2:呼叫 base 前,先利用 method 把參數都變成大寫
public InheritTest(string name): base(ModifyBase(name))
{
}
private static string ModifyBase(string newName)
{
return newName.ToUpper();
}
}
}
namespace MVATwentyQuestions
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine();
Test nTest = new Test("Base");
Console.WriteLine(nTest._name);
InheritTest iTest = new InheritTest("NewName");
Console.WriteLine(iTest._name);
}
}
}
Demo1 結果
Demo2 結果
星期二, 9月 09, 2014
[C#] WebForm 之間傳遞參數
論壇問題
在 WebForm 之間傳遞參數利用 QueryString 和 Session 來練習傳遞參數
using System.Data; namespace PassPara { public partial class WebForm1 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DataTable dt = new DataTable("Demo"); dt.Columns.Add("ProdNO", typeof(int)); dt.Columns.Add("ProdName", typeof(string)); dt.Rows.Add(1, "Visial Studio 2013"); dt.Rows.Add(2, "SQL Server 2014"); dt.Rows.Add(3, "Windows Server 2012 R2"); dt.Rows.Add(4, "Office 365"); dt.Rows.Add(5, "Windows Azure"); gvData.DataSource = dt; gvData.DataBind(); } } protected void btnShowData_Click(object sender, EventArgs e) { // 避免重覆選取,要先把 Text 內容清空 lblResult.Text = ""; // 利用 foreach 方式來搜尋使用者勾選資料 foreach (GridViewRow row in gvData.Rows) { // 確認 RowType 是 DataRow if (row.RowType != DataControlRowType.DataRow) continue; // 利用 FindControl 來找到 CheckBox 控件 CheckBox cb = row.FindControl("cbChecked") as CheckBox; if (cb == null || !cb.Checked) continue; lblResult.Text += row.Cells[2].Text + "<br>"; } } private List<string> getCheck(GridView gvData) { // 利用 LINQ 方式找出使用者勾選資料 List<string> checkresult = (from GridViewRow r in gvData.Rows where (r.FindControl("cbChecked") as CheckBox).Checked == true select gvData.Rows[r.RowIndex].Cells[2].Text.ToString()).ToList<string>(); return checkresult; } protected void btnQueryString_Click(object sender, EventArgs e) { Response.Redirect("QueryStringPage.aspx?Data=" + Server.UrlEncode(string.Join(",", getCheck(gvData)))); } protected void btnSession_Click(object sender, EventArgs e) { Session["Data"] = getCheck(gvData); Response.Redirect("SessionPage.aspx"); } } }
星期一, 9月 08, 2014
[C#] 尋找控制項
論壇問題
利用字串(pic1)要尋找控制項(PictureBox)這應該算是 Form 控制項的基礎,利用 Controls.Find() 來確定控制項存在語法,並抓取控制項屬性
private void ControlsFind_Load(object sender, EventArgs e) { string picName = "pic1"; Control[] result = this.Controls.Find(picName, false); // 該陣列長度為零,表示沒有尋找到相關控件 if (result.Length == 0) return ; // 判斷該控件是否為 PictureBox 且可轉型為 PictureBox if (!(result[0] is PictureBox)) return; PictureBox pb = result[0] as PictureBox; if (pb == null) return; // 抓取該 PictureBox 屬性,並透過 MessageBox 來顯示 StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("Name:{0}", pb.Name)); sb.AppendLine(string.Format("Size:{0}", pb.Size)); sb.AppendLine(string.Format("Font:{0}", pb.Font)); MessageBox.Show(sb.ToString(), "PictureBox 相關屬性", MessageBoxButtons.OK, MessageBoxIcon.Information); }
- 參考資料
- 論壇問題出處
星期三, 9月 03, 2014
[C#] 字串加解密
MVA Twenty C# Questions Explained - [11 Explain how to encrypt/decrypt a string in .NET]
利用 TripleDES 來對字串進行加解密,這篇就單純紀錄課程中的 Code 而已
利用 TripleDES 來對字串進行加解密,這篇就單純紀錄課程中的 Code 而已
namespace MVATwentyQuestions
{
class Program
{
static void Main(string[] args)
{
string plainText = "This is plain text that we will encrypt";
string password = "P@$$w0rd";
string depassword = "doesn't work";
Console.WriteLine(plainText);
Console.WriteLine();
// create a new instance of our encryption class passing in the password as the key
DESEncrypt testEncrypt = new DESEncrypt();
string encText = testEncrypt.EncryptString(plainText, password);
Console.WriteLine("****** Encrypted text ******");
Console.WriteLine(encText);
Console.WriteLine();
Console.WriteLine("****** Decrypted text ******");
//string plain = testEncrypt.DecryptString(encText, password);
string plain = testEncrypt.DecryptString(encText, depassword);
Console.WriteLine(plain);
Console.WriteLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
namespace MVATwentyQuestions
{
class DESEncrypt
{
static TripleDES CreateDES(string key)
{
MD5 md5 = new MD5CryptoServiceProvider();
TripleDES des = new TripleDESCryptoServiceProvider();
des.Key = md5.ComputeHash(Encoding.Unicode.GetBytes(key));
des.IV = new byte[des.BlockSize / 8];
return des;
}
public string EncryptString(string plainText, string password)
{
// first we convert the plain text into a byte array
byte[] plainTextBytes = Encoding.Unicode.GetBytes(plainText);
// use a memory stream to hold the bytes
MemoryStream myStream = new MemoryStream();
// create the key and initialization vector using the password
TripleDES des = CreateDES(password);
// create the encoder that will write to the memory stream
CryptoStream cryptStream = new CryptoStream(myStream, des.CreateEncryptor(), CryptoStreamMode.Write);
// we now use the crypto stream to write our byte array to the memory stream
cryptStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptStream.FlushFinalBlock();
// change the encrypted stream to a printable version of our encrypted string
return Convert.ToBase64String(myStream.ToArray());
}
public string DecryptString(string encryptedText, string password)
{
// convert our encrypted string to a byte array
byte[] encryptedTextBytes = Convert.FromBase64String(encryptedText);
// create a memory stream to hold the bytes
MemoryStream myStream = new MemoryStream();
// create the key and initialization vector using the password
TripleDES des = CreateDES(password);
// create our decoder to write to the stream
CryptoStream decryptStream = new CryptoStream(myStream, des.CreateDecryptor(), CryptoStreamMode.Write);
// we now use the crypto stream to the byte array
decryptStream.Write(encryptedTextBytes, 0, encryptedTextBytes.Length);
decryptStream.FlushFinalBlock();
// convert our stream to a string value
return Encoding.Unicode.GetString(myStream.ToArray());
}
}
}
星期二, 9月 02, 2014
[C#] 動態建立 MenuStrip
論壇問題 - 動態建立 MenuStrip,功能表的概念跟組織圖、BOM 表、會計編號類似,說穿都是樹狀圖,因此 Table Schema 是一大重點
SQL Server 上設定 Script
SQL Server 上設定 Script
-- 在 SQL Server 2014 Express 上的 AdventrueWork2012 進行 USE [AdventureWorks2012] GO -- 建立 Table Schema IF OBJECT_ID('MenuStrip') IS NOT NULL DROP TABLE MenuStrip CREATE TABLE [dbo].[MenuStrip]( [MenuNO] [char](2) NOT NULL CONSTRAINT [DF_MenuStrip_MenuNO] DEFAULT (''), [ParentID] [char](20) NOT NULL CONSTRAINT [DF_MenuStrip_ParentID] DEFAULT (''), [ParentOrder] [tinyint] NOT NULL CONSTRAINT [DF_MenuStrip_ParentOrder] DEFAULT ((0)), [ChildID] [char](20) NOT NULL CONSTRAINT [DF_MenuStrip_ChildID] DEFAULT (''), [ChildName] [nchar](40) NOT NULL CONSTRAINT [DF_MenuStrip_ChildName] DEFAULT (''), [ChildOrder] [tinyint] NOT NULL CONSTRAINT [DF_MenuStrip_ChildOrder] DEFAULT ((0)), CONSTRAINT [PK_MenuStrip] PRIMARY KEY CLUSTERED ( [ChildID] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO -- 建立測試資料,從 VS 2013 功能表中挑幾個選項出來建立資料 INSERT INTO MenuStrip (MenuNO , ParentID , ParentOrder , ChildID , ChildName , ChildOrder) VALUES ('01','R',1,'Files',N'檔案',0), ('01','Files',1,'NewFile',N'新增',1), ('01','NewFile',1,'Project',N'專案',1), ('01','Files',1,'OpenFile',N'開啟',2), ('01','Files',1,'End',N'結束',3), ('01','R',2,'Edit',N'編輯',0), ('01','Edit',2,'Cut',N'剪下',1), ('01','Edit',2,'Paste',N'貼上',2), ('01','Edit',2,'SearchReplace',N'尋找和取代',3), ('01','SearchReplace',2,'QuitSearch',N'快速尋找',1), ('01','SearchReplace',2,'QuitReplace',N'快速取代',2) GO -- 建立 Store Procedure IF OBJECT_ID('uspDataFill') IS NOT NULL DROP PROCEDURE uspDataFill GO -- 利用 SQL Server CTE 跑出樹狀圖(TreePath 欄位),只是為了方便了解資料路徑,在 C# 中並不會使用到它 CREATE PROCEDURE uspDataFill (@MenuNO char(2)) AS BEGIN ; WITH CTE AS ( SELECT MenuNO , ParentID , ParentOrder , ChildID , ChildName , ChildOrder , CAST(RTRIM(ParentID) + CAST(ParentOrder AS char(1)) + '_' + CAST(ChildOrder AS CHAR(1)) + ChildName AS nVARCHAR(200)) AS TreePath FROM MenuStrip WHERE MenuNO = @MenuNO AND ParentID = 'R' UNION ALL SELECT MS.MenuNO , MS.ParentID , MS.ParentOrder , MS.ChildID , MS.ChildName , MS.ChildOrder , CAST(RTRIM(T.TreePath) + '_' + CAST(MS.ChildOrder AS CHAR(1)) + MS.ChildName AS NVARCHAR(200)) FROM CTE AS T JOIN MenuStrip AS MS ON T.MenuNO = MS.MenuNO AND T.ChildID = MS.ParentID ) SELECT * FROM CTE ORDER BY TreePath END GO -- 觀察 CTE 產生的 TreePath 資料 EXEC uspDataFill '01'
星期一, 9月 01, 2014
[C#] 關鍵字變色
拿論壇問題來練習
要根據輸入關鍵字,把 GridView 內容內的關鍵字變成紅色
using System.Data;
namespace HighlightContent
{
public partial class HighlightContent : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dt = new DataTable("Demo");
dt.Columns.Add("Data", typeof(string));
dt.Rows.Add("SQL Server 2014");
dt.Rows.Add("SQL Server 2012");
dt.Rows.Add("SQL Server 2008 R2");
dt.Rows.Add("SQL Server 2008");
dt.Rows.Add("Windows Server 2012 R2");
dt.Rows.Add("Windows Server 2012");
dt.Rows.Add("Windows Server 2008 R2");
dt.Rows.Add("Windows Server 2008");
gvData.DataSource = dt;
gvData.DataBind();
txtKeyword.AutoPostBack = true;
}
}
protected void txtKeyword_TextChanged(object sender, EventArgs e)
{
string keyword = txtKeyword.Text;
if (string.IsNullOrEmpty(keyword)) return;
string highlight = "" + keyword + "";
foreach (GridViewRow row in gvData.Rows)
{
// 重覆輸入關鍵時,要先把之前的 HTML 拿掉
row.Cells[0].Text = splitHTML(row.Cells[0].Text).Replace(keyword, highlight);
}
}
public static string splitHTML(string html)
{
string split = html;
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"<[^>]*>");
split = regex.Replace(split, "");
return split;
}
}
}