星期二, 9月 30, 2014

[Excel] 刪除重複資料

使用 Excel 功能來刪除重覆資料
  • 示範資料
[Excel] 刪除重複資料 -0

星期一, 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;   
        }
    }
}
[C#] PictureBox 顯示圖片

星期五, 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]'
  )
[SQL] Linked Server 抓取 Text 檔案

星期四, 9月 25, 2014

[Excel] 選取全部資料

以往要選取 Excel 內的資料,都是利用滑鼠從最後一筆資料的最後一個欄位往上選取,但資料量很龐大,光是要利用捲軸找到最後一筆資料就很麻煩,還常常拉過頭,Orz ~~

其實 Excel 內有快速鍵可以使用, Ctrl + Shift + 方向鍵選取資料(以最左上角為起點的話,方向鍵右 + 方向鍵下或方向鍵下 + 方向鍵右),就可以快速選取全部資料

[Excel] 選取全部資料

星期三, 9月 24, 2014

[C#] Structs VS Classes

MVA Twenty C# Questions Explained - [01 Structs VS Classes],聽完後順道找些資料來了解並整理記錄成筆記

Structs 和 Classes 的比較

StructsClasses
Value typeRefrence 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;
        }
    }
}
[LINQ] 累計加總

星期一, 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 基本操作

星期日, 9月 21, 2014

多功能筆盒

研討會問卷禮,由上往下
  • 黃:螢光筆
  • 灰:自動鉛筆
  • 黑:黑色原子筆
  • 藍:藍色原子筆
  • 紅:紅色原子筆
IMG_1031

星期五, 9月 19, 2014

[SQL] 避免在 SSMS 圖形介面上修改資料型態

同事告知更新自己電腦上的 SQL Server 欄位資料型態時,常常會出現 Timeout 的情況,建議更新欄位資料型態,千萬不要利用 SSMS 去做,一定要利用 T-SQL 語法進行

[SQL] 避免在 SSMS 圖形介面上修改資料型態-3

星期三, 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 路徑
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#] 格式化日期資料

拿論壇問題來練習一下
資料在 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
[ASP.NET] 格式化日期資料-1

[ASP.NET] 格式化日期資料-2

在 GridView 控件上設定完成後,可以在 .aspx 內看見 DataFormatString 設定值

[ASP.NET] 格式化日期資料-3
  • 利用 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();
                }
            }
        }
    }
}
[ASP.NET] 格式化日期資料-4

星期三, 9月 10, 2014

[C#] 呼叫父建構子

MVA Twenty C# Questions Explained - [05 How do you call a base constructor in C#?]
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 結果
[C#] 呼叫父建構子 -1

Demo2 結果
[C#] 呼叫父建構子 -2

星期二, 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");
        }
    }
}
[ASP.NET] WebForm 之間傳遞參數-1

星期一, 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);
}
[C#] 尋找控制項

星期三, 9月 03, 2014

[C#] 字串加解密

MVA Twenty C# Questions Explained - [11 Explain how to encrypt/decrypt a string in .NET]

利用 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 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'
[C#] 動態建立 MenuStrip-1

星期一, 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;
        }
    }
}
[ASP.NET] 關鍵字變色