星期二, 12月 30, 2014

[C#] 根據 TextBox 顯示 Combobox

論壇問題
combobox 如果用點選的話是沒問題的,但如果需要用輸入text就去抓相對應的value,我應該怎麼寫呢?假設 value 有: 1-水壺 2-鉛筆 3-電腦,我在輸入 1 的時候 combobox 會出現 "1-水壺" 並取得相關的 value,而不用打開下來選單來選擇該選項。
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Items.Add("1-水壺");
            comboBox1.Items.Add("2-鉛筆");
            comboBox1.Items.Add("3-電腦");
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string target = textBox1.Text;
            if (string.IsNullOrEmpty(target)) return;

            comboBox1.Text = string.Empty;
            string comboText = string.Empty;
            foreach (string item in comboBox1.Items)
            {
                comboText = item.ToString();
                if (comboText.Substring(0, target.Length) != target) continue;
                comboBox1.Text = comboText;
                break;
            }
        }
    }
}
[C#] 根據 TextBox 顯示 Combobox

星期一, 12月 29, 2014

[Azure] VM - 新增資料磁碟

在 Windows Azure VM 上掛載資料硬碟,模擬 VM 硬碟空間不足時,需要額外的硬碟空間存防資料,記錄參與 2014 Wndows Azure 開發訓練營和閱讀網路資料的筆記。

建立 VM 後,可以從下圖中看見 C 為 OS,D 為 Temporary Storage,只提供資料暫存,VM 關機或重新啟動,資料就可能會遺失,因此必須建立虛擬硬碟 (vhd),並掛載到 VM 上,才具備保存資料的功能,另 VM 掛載資料硬碟數量,會根據開 VM 的等級而有所限制,EX:A1 只能掛載 1 顆,限制請參考官方網站規格說明

[Azure] VM - 新增空白磁碟-0

星期二, 12月 23, 2014

[Azure] VM - 啟用 IIS

在已建立好的 VM 上安裝 IIS 並開啟 HTTP 80 Port 來連接 IIS,記錄參與 2014 Wndows Azure 開發訓練營的筆記。

在 VM 上安裝 IIS,Manage => Add Role and Features

[Azure] VM - 啟用 IIS-1
Step by Step 的過程中,在 Server Roles 勾選 Web Server(IIS)

星期一, 12月 22, 2014

[ADO.NET] 彙總函數練習

練習 ADO.NET 彙總函數的使用 ~~
namespace AggDeno
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataTable dtAgg = new DataTable();
        DataTable dtDataTable = new DataTable();
        private void Form1_Load(object sender, EventArgs e)
        {
            dtFill();
        }

        private void dtFill()
        {
            dtAgg.Columns.Add("Alias", typeof(string));
            dtAgg.Columns.Add("Data",typeof(decimal));
            dtAgg.Rows.Add("EG-2A",369);
            dtAgg.Rows.Add("EG-2A",344);
            dtAgg.Rows.Add("IA1-1X", 322.88);
            dtAgg.Rows.Add("IA1-1X", 0.335);
            dtAgg.Rows.Add("IQ1-4X", 0.225);
            dtAgg.Rows.Add("IQ1-4X", 3.6);
            dtAgg.Rows.Add("IQ1-4X", 222.5);
            dgvData.DataSource = dtAgg;

            // Clone() 複製原 DataTable Schema
            // Copy()  複製原 DataTable Schema 和 Data
            dtDataTable = dtAgg.Clone();
            dgvDataTable.DataSource = dtDataTable;
        }

        private void btnADO_Click(object sender, EventArgs e)
        {
            dtDataTable.Rows.Clear();

            // 利用 ToTable() 找出 Alias 唯一值
            DataTable dtLoop = dtAgg.DefaultView.ToTable(true, "Alias");

            string filter = string.Empty;
            string Alias = string.Empty;
            foreach (DataRow dr in dtLoop.Rows)
            {
                Alias = dr["Alias"].ToString();

                DataRow drNew = dtDataTable.NewRow();
                drNew["Alias"] = Alias;
                filter = string.Format("Alias = '{0}'", Alias);
                drNew["Data"] = dtAgg.Compute("AVG(Data)", filter);
                dtDataTable.Rows.Add(drNew);
            }
        }

        private void btnDataTableLINQ_Click(object sender, EventArgs e)
        {
            dtDataTable.Rows.Clear();

            IEnumerable<string> loop = dtAgg.AsEnumerable().Select(Row => Row.Field<string>("Alias")).Distinct();

            foreach (string Alias in loop)
            {
                decimal avg = dtAgg.AsEnumerable().Where(dr => dr.Field<string>("Alias") == Alias).Average(dr => dr.Field<decimal>("Data"));

                DataRow drNew = dtDataTable.NewRow();
                drNew["Alias"] = Alias;
                drNew["Data"] = avg;
                dtDataTable.Rows.Add(drNew);
            }
        }

        private void btnLINQ_Click(object sender, EventArgs e)
        {

            var result = dtAgg.AsEnumerable().GroupBy(datarow => datarow.Field<string>("Alias")).Select(g => new { Alias = g.Key , AVG = g.Average(a => a.Field<decimal>("Data"))}).ToList();

            dgvLINQ.DataSource = result;
        }
    }
}
[C#] 彙總函數練習

星期三, 12月 17, 2014

貼紙

研討會中按讚的贈品 - 小光貼紙

貼紙

星期二, 12月 16, 2014

[Azure] VM - 建立 Windows 虛擬機器

在 Windows Azure 上快速建立出一個 Windows VM 來使用,記錄參與 2014 Wndows Azure 開發訓練營和閱讀 MVA 上影片的筆記。

新增

[Azure] VM - 建立 Windows 虛擬機器-1

計算 => 虛擬機器 => 快速建立,設定相關資訊;假如是從 "組件庫" 來建立的話,可以設定進階選項。
  • DNS 名稱:VM 對外的 DNS 名稱,必須是 Global Only
  • 影像:欲建立的作業系統
  • 大小:老師建議最少要到開標準 A2 以上,標準 A2 以下進入 VM 會非常緩慢
  • 使用者名稱:無法輸入 user、guest、、admin 和 administrator 這類常見的名稱,此為利用遠端桌面(RDP)連進 VM 的帳號
  • 密碼:必須滿足複雜密碼原則(所定義的密碼長度必須超過八個字元,且包含有小寫英文、大寫英文、數字及符號其中三種。)
  • 區域:東亞,機房位於香港,
  • 訂閱用戶:付款依據
[Azure] VM - 建立 Windows 虛擬機器-2

星期一, 12月 15, 2014

[C#] WebBrowser

整理上課筆記

一直覺的 WebBrowser 控件好像沒有甚麼實際用途,上課時老師有提到,實務上可以把 Web 上的最新消息,透過 WebBrowser 來顯示,這樣就不用設計 WinForm 版本介面
namespace WebBrowserDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Form 上每個控件的 Anchor 設定
            lblURL.Anchor = AnchorStyles.Left | AnchorStyles.Top;
            txtURL.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
            btnGO.Anchor = AnchorStyles.Top | AnchorStyles.Right;
            webBrowser1.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;

            // 顯示該電腦 IE 首頁並顯示在 txtURL 內
            webBrowser1.GoHome();
        }

        private void btnGO_Click(object sender, EventArgs e)
        {
            runURL();
        }

        private void txtURL_KeyUp(object sender, KeyEventArgs e)
        {
            // 使用者輸入完後,直接按 Entry 執行
            if (e.KeyCode == Keys.Enter) runURL();
        }

        private void runURL()
        {
            webBrowser1.Navigate(txtURL.Text);
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // 使用者操作 WebBrowser 內連結時,必須把點擊的 URL 傳回 txtURL 內顯示
            string url = webBrowser1.Url.ToString();
            if (string.IsNullOrEmpty(url)) return;
            txtURL.Text = url;
        }
    }
}

執行程式會顯示 IE 首頁

[C#] WebBrowser-1

利用 Google 搜尋 Blog,可以看見 txtURL 會顯示現在的網址

[C#] WebBrowser-2
[C#] WebBrowser-3

星期五, 12月 12, 2014

[SQL] Merge 應用

此範例同 [SQL] OUTPUT 語法,差別在於 OUPUT 與法是假如 StockQty 內產品一定存在,而 Merge 則是不一定存在,且庫存量為 0 時,必須把產品刪除,藉此練習 OUTPUT 和 Merge 語法

下列在 AdventureWorks 中利用產品(Production)、庫存量(StockQty)和入領料(Stock、StockDetail)來說明 Merge 語法
  • 建立基礎 Table 並插入 Sample Data
IF OBJECT_ID('StockQty') IS NOT NULL
  DROP TABLE StockQty
 
IF OBJECT_ID('Stock') IS NOT NULL
  DROP TABLE Stock

IF OBJECT_ID('StockDetail') IS NOT NULL
  DROP TABLE StockDetail
 
IF OBJECT_ID('Production') IS NOT NULL
  DROP TABLE Production

CREATE TABLE Production (ProdID int Primary key, ProdName nchar(50))
INSERT INTO Production VALUES(1,N'SQL Server 2014')
INSERT INTO Production VALUES(2,N'SQL Server 2012')
INSERT INTO Production VALUES(3,N'SQL Server 2008 R2')
INSERT INTO Production VALUES(4,N'SQL Server 2008')
INSERT INTO Production VALUES(5,N'SQL Server 2005')

-- StockQty 沒有任何資料,當 StockDetail 有資料時,
-- 會透過 Merge 語法來 insert、update 和 delete StockQty Table 內資料
CREATE TABLE StockQty (ProdID int Primary key, Qty int)

CREATE TABLE Stock (SID int Primary key, [Date] date)
CREATE TABLE StockDetail (SID int Primary key(SID,ProdID), ProdID int , Qty int)
GO

星期二, 12月 09, 2014

[ADO.NET] 計算 DataTable 資料筆數

論壇問題
從 Database 中把 DataTable 後,把重覆值去除掉後當成 comboBox 資料來源,希望點選 comboxBox 時,可以顯示該選項在 DataTable 內的資料筆數
想法是利用 T-SQL DISTINCT 語法找出唯一値當成 comboxBox 資料來源,再根據使用者點選資料,進入 Database 計算資料筆數,論壇討論則是把資料通通抓到 C# 中來處理,剛好拿來練習 ADO.NET
namespace ComboBoxSearch
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // dtCombo 為全域變數
        DataTable dtCombo = new DataTable("Demo");

        private void Form1_Load(object sender, EventArgs e)
        {
            // 資料來源建立
            sourceFill();

            // 設定 ComboBox 的 DropDownStyle 
            cboList.DropDownStyle = ComboBoxStyle.DropDownList;
            cboDataTable.DropDownStyle = ComboBoxStyle.DropDownList;
            // 設定 ComboBox 一開始不顯示任何選項
            cboList.SelectedIndex = -1;
            cboDataTable.SelectedIndex = -1;
            // 不允許 DataGridView 可以新增資料
            gvData.AllowUserToAddRows = false;
        }

        private void sourceFill()
        {
            // dtCombo Schema 和 Data 建立
            dtCombo.Columns.Add("ColName",typeof(string));
            dtCombo.Rows.Add("A");
            dtCombo.Rows.Add("A");
            dtCombo.Rows.Add("A");
            dtCombo.Rows.Add("B");
            dtCombo.Rows.Add("B");
            dtCombo.Rows.Add("C");
            dtCombo.Rows.Add("C");
            dtCombo.Rows.Add("C");
            dtCombo.Rows.Add("C");
            dtCombo.Rows.Add("D");
            dtCombo.Rows.Add("D");
            dtCombo.Rows.Add("D");
            dtCombo.Rows.Add("D");
            dtCombo.Rows.Add("D");

            // 資料來源為 List
            List<string> uniqueLINQ = dtCombo.AsEnumerable().Select(row => row.Field<string>("ColName")).Distinct().ToList();
            cboList.DataSource = uniqueLINQ;

            // 資料來源為 DataTable
            DataTable uniqueDataTable = dtCombo.DefaultView.ToTable(true, "ColName");
            cboDataTable.DataSource = uniqueDataTable;
            cboDataTable.ValueMember = "ColName";
            cboDataTable.DisplayMember = "ColName";

            // 把 dtCombo 資料顯示出來,方便比對資料
            gvData.DataSource = dtCombo;
        }

        private void gvData_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (!gvData.Columns[e.ColumnIndex].Name.Equals("ColName")) return;

            string item =
                cboList.SelectedIndex == -1
                ? string.Empty
                : cboList.SelectedItem.ToString();
   
            string value = 
                cboDataTable.SelectedIndex == -1
                ? string.Empty
                : cboDataTable.SelectedValue.ToString();

            e.CellStyle.BackColor = SystemColors.Control;
            if (e.Value.ToString() == item || e.Value.ToString() == value) 
              e.CellStyle.BackColor = Color.LightGray;
        }

        private void cboList_SelectionChangeCommitted(object sender, EventArgs e)
        {
            // LINQ 作法
            if (cboList.SelectedIndex == -1) return;
            string item = cboList.SelectedItem.ToString();

            string result = dtCombo.AsEnumerable().Where(row => row.Field<string>("ColName") == item).Count().ToString();

            txtList.Text = result;
            gvData.Refresh();
        }

        private void cboDataTable_SelectionChangeCommitted(object sender, EventArgs e)
        {
            // ADO.NET 作法
            if (cboDataTable.SelectedIndex == -1) return;
            string value = cboDataTable.SelectedValue.ToString();

            string filter = string.Format("ColName = '{0}'", value);
            string result = dtCombo.Compute("COUNT(ColName)", filter).ToString();

            txtDataTable.Text = result;
            gvData.Refresh();
        }
    }
}

練習時發現,當 Form 一執行時都會觸發 ComboBox SelectedIndexChanged 事件,在 MSDN ComboBox.SelectionChangeCommitted 事件,看見這段說明
只有當使用者變更下拉式方塊選擇時,才會引發 SelectionChangeCommitted。 請勿使用 SelectedIndexChanged 或 SelectedValueChanged 來擷取使用者變更,因為當以程式方式變更選擇時,也會引發這些事件。
ComboBox 預設點擊事件為 SelectedIndexChanged,所以也就很直覺地把 Code 寫在裡面,Orz ~~

星期一, 12月 08, 2014

[Word] 目錄

從 2003 開始就有的功能,到了 2013 終於實際操作 ~~ ^^'' ~~

Step1:設定標題

在 word 內輸入第一章,可以看見 Word 樣式是顯示 "內文"

目錄-1

全選 "第一章"字樣後,改設定為 "標題 1" 後,可以在第一章字樣前看見下圖綠色框框符號

目錄-2

在其他頁面上輸入第二章和第三章;第三章第一節、第三章第二節設定為 "標題 2 ",可以再導覽內看見設定的標題

目錄-3

設定標題時,理論上導覽功能寄會自動出現,沒有出現的話,請至檢視 => 勾選功能窗格,就可以叫出導覽功能

目錄-4

星期三, 12月 03, 2014

[C#] 使用者控制項

了解如何改寫使用者控制項時,在 MSDN 發現這篇文章 逐步解說:使用 Visual C# 撰寫使用者控制項,動手實作並把文章內的 Code 整理起來

實作這篇文章時最大的收穫是,原來要 override 時,VS 有快取的方式可以使用,之前看到範例,都會覺得怎麼這麼利害,Method 內的 Object Sender 和 EventArgs e 這兩個參數要怎麼知道,尤其是 EventArgs,不會都必須查詢 MSDN,然後再複制貼上到 VS 內吧,Orz ~~

[C#] 使用者控制項-1

[C#] 使用者控制項-2

星期二, 12月 02, 2014

[Win] iSCSI 目標伺服器 - MPIO

完成 iSCSI 目標伺服器和 iSCSI 啟動伺服器設定後,就可以進行檔案傳輸,從下圖的效能監視器內可以發現,雖然有設定都有設定兩張網路卡,但實際傳輸檔案時,還是只透過一張網路卡進行傳輸,要透過多張網路卡傳輸,還必須在 iSCSI 啟動伺服器上,設定 MPIO 功能
[Win] iSCSI 目標伺服器 -MPIO-1