星期一, 11月 28, 2016

[C#] Windows Service

根據這篇 MSDN 文章 逐步解說:在元件設計工具中建立 Windows 服務應用程式 的筆記,該文章是利用 Windows Service 的啟動、停止和 Timer 來對事件檢視器新增資料,藉此觀察 Windows Service 狀態

在 VS 2015 上建立 Windows Service 範本,路徑是 [Visucal C# => 傳統桌面 => Windows 服務],一開始要找到該範本就卡關,利用 "Windows Service" 去搜尋,完全找不到,以為要在 VS 上另外安裝,Google 後才恍然大悟,中文版應該用 "Windows 服務" 去找才對啦,Orz

[C#] Windows Service-6

星期三, 11月 16, 2016

[C#] Control.Visible 和 DataBinding

實務上有把控件隱藏起來的設計,使用時發現資料無法回傳 DB,才發現原來原來控件隱藏的時間點很重要
  • 控件加入 Form 隱藏,DataBinding 無法正常作動
  • 控件加入 Form 隱藏,預期效果
測試只發現上述說明,後來才找到這篇 技術論壇討論,說明該情況是因為 Binding.Fomat Event 加入前隱藏的話,Format Event 就不會被觸發。

簡易範例來記錄

Form Layout

[C#] Control.Visible 和 DataBinding-1

星期六, 11月 12, 2016

[C#] ComboBox DropDownList (續)

在這篇 [C#] ComboBox DropDownList 提到 Item 和 DataBinding 資料,字元長度要一樣,DropDownList 才會正確顯示資料,實務上是把 Item 資料放在 DB Table (以下稱呼 ComboBoxData Table) 內,因為會有各式各樣的 ComboBox Item 資料放在這,所以 ComboBoxData Table 資料欄位長度一定和 Data Table 欄位長度不一樣,因此兩者必須互相搭配才成正確顯示 DropDownList 資料

簡易範例:利用自訂 ComboBox 控件來正確顯示 DropDownList 資料

方案內容

[C#] ComboBox DropDownList (續)-1

WinForm Layout

[C#] ComboBox DropDownList (續)-2

星期四, 11月 10, 2016

[C#] 避免 Hard Code

論壇上偶而會看見的寫法
comboBox1.GetType().ToString() == "System.Windows.Forms.ComboBox"
該寫法程式會正確判斷也不會有任何異常,但根本是挑戰自我專注力,只要打錯任何一個字,就變成 false,會建議改成下列寫法
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private void Form1_Load(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            // 利用 Type 判斷
            if (comboBox1.GetType() == typeof(ComboBox))
                sb.AppendLine("Type 判斷:Yes");
            else
                sb.AppendLine("Type 判斷:NO");

            // 利用 ToString() 字串判斷
            if (comboBox1.GetType().ToString() == "System.Windows.Forms.ComboBox")
                sb.AppendLine("ToString() 字串判斷:Yes");
            else
                sb.AppendLine("ToString() 字串判斷:NO");

            // 利用 ToString() 字串判斷,故意大小寫錯一個
            if (comboBox1.GetType().ToString() == "System.Windows.Forms.Combobox")
                sb.AppendLine("ToString() 字串判斷,故意大小寫錯一個字:Yes");
            else
                sb.AppendLine("ToString() 字串判斷,故意大小寫錯一個字:NO");

            MessageBox.Show(sb.ToString(), "控件判斷", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
[C#] 避免 Hard Code

星期三, 11月 09, 2016

[C#] DataGridView 內顯示民國年

在 DataGridView 內透過 Taiwan Calendar 來把西元年轉換為民國年
namespace dgvDate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.AutoGenerateColumns = false;

            // 建立 Column
            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Data",
                Name = "ColAD",
                HeaderText = "西元年",
                Width = 100
            });

            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Data",
                Name = "ColSimple",
                HeaderText = "民國年 - 簡單",
                Width = 100
            });

            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Data",
                Name = "ColFull",
                HeaderText = "民國年 - 完整",
                Width = 100
            });

            dataGridView1.Columns.Add(new DataGridViewTextBoxColumn
            {
                DataPropertyName = "Data",
                Name = "ColCustom",
                HeaderText = "民國年 - 自訂",
                Width = 100
            });

            // 資料來源
            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Data", typeof(DateTime));
            dt.Rows.Add(1, DateTime.Today);
            dataGridView1.DataSource = dt;

            // 民國年設定
            CultureInfo ci = new CultureInfo("zh-TW", true);
            ci.DateTimeFormat.Calendar = new TaiwanCalendar();

            dataGridView1.Columns["ColSimple"].DefaultCellStyle.FormatProvider = ci;
            dataGridView1.Columns["ColSimple"].DefaultCellStyle.Format = "d";

            dataGridView1.Columns["ColFull"].DefaultCellStyle.FormatProvider = ci;
            dataGridView1.Columns["ColFull"].DefaultCellStyle.Format = "D";

            dataGridView1.Columns["ColCustom"].DefaultCellStyle.FormatProvider = ci;
            dataGridView1.Columns["ColCustom"].DefaultCellStyle.Format = "yyy-MM-dd";
        }
    }
}
[C#] DataGridView 內顯示民國年

星期二, 11月 08, 2016

[C#] Constructor 建構子 - this

看見朋友 Blog 筆記、且也在論壇上看見 Constructor 建構子搭配 this 使用,腦海中就只有呼叫父 class 建構子 base 用法,趁這個機會了解筆記

簡易範例
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            demo d = new demo();

            Console.WriteLine("--------------------------");

            demo d1 = new demo("this 測試,呼叫預設建構子");

            Console.WriteLine("--------------------------");

            demo d2 = new demo("this 測試" , "呼叫指定建構子");
        }
    }

    public class demo
    {
        public demo()
        {
            Console.WriteLine("預設建構子");
        }

        public demo(string data) : this()
        {
            Console.WriteLine($"建構子1:{data}");
        }

        public demo(string data1 , string data2) : this(data2)
        {
            Console.WriteLine($"建構子2:{data1}-{data2}");
        }

    }
}
[C#] Constructor 建構子 - this

星期一, 11月 07, 2016

[C#] ComboBox DropDownList

使用 ComboBox.DropDownList 時,發現會無法正確地顯示資料,還不是每一個 ComboBox 都會發生,後來釐清才發現,原來設定 DropDownList 時,Item 和 DataBinding 的資料,字元長度要一樣才行

簡易範例 - cboShow 用來顯示使用者 cboSelected 和 chkEmpty 組合資料,完全一模一樣就會顯示在 cboShow 上
namespace DropDownList
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // B 和 D 故意空一格
            cboShow.Items.Add("A");
            cboShow.Items.Add("B ");
            cboShow.Items.Add("C");
            cboShow.Items.Add("D ");
            cboShow.Items.Add("E");

            cboSelected.Items.Add("A");
            cboSelected.Items.Add("B");
            cboSelected.Items.Add("C");
            cboSelected.Items.Add("D");
            cboSelected.Items.Add("E");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // 一律先空白
            cboShow.SelectedIndex = -1;
            // 組合使用者選擇資料
            string result = cboSelected.Text.Trim();
            if (checkEmpty.Checked == true) result += " ";
            // 設定顯示
            cboShow.Text = result;
        }
    }
}

[C#] ComboBox DropDownList

星期日, 11月 06, 2016

[C#] ComboBox 預設值

要指定 ComboBox Item 中的選項(Item),要透過指定 ComboBox.SelectedIndex 來做到

簡易範例
namespace ComboBoxDefaultValue
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Items.Add("A");
            comboBox1.Items.Add("B");
            comboBox1.Items.Add("O");
            comboBox1.Items.Add("AB");

            // ComboBox 預設顯示值為 O
            comboBox1.SelectedIndex = 2;
        }

        private void btnAssign_Click(object sender, EventArgs e)
        {
            // 指定顯示 AB
            comboBox1.SelectedIndex = comboBox1.FindStringExact("AB");
        }

        private void btnEmpty_Click(object sender, EventArgs e)
        {
            // ComboBox 不顯示任何資料
            comboBox1.SelectedIndex = -1;
        }

        private void btnExt_Click(object sender, EventArgs e)
        {
            // 指定顯示 Item,不存在就顯示第一個 Item
            comboBox1.SelectedIndex = comboBox1.FindStringExactDefault("AA");
        }
    }

    /// <summary>
    /// ComboBox 擴充方法
    /// </summary>
    public static class ExtComboBox
    {
        /// <summary>
        /// 利用 FindStringExtra() 搜尋,沒有該 Item 的話,就回傳 Index = 0,而非 -1
        /// </summary>
        /// <param name="cbo">ComboBox 控件</param>
        /// <param name="target">目標搜尋字串</param>
        /// <returns>該 Item 索引</returns>
        public static int FindStringExactDefault(this ComboBox cbo, string target)
        {
            int index = cbo.FindStringExact(target);
            return index == -1 ? 0 : index;
        }
    }
}

星期五, 11月 04, 2016

[Azure] Microsoft Azure Storage Explorer

Microsoft Azure Storage Explorer (ASE)是官方 Storage 管理工具,目前版本是 0.8.5,下載來使用

建立 Storage Account 要透過 ASE 來操作看看

[Azure] Microsoft Azure Storage Explorer-1


沒想到在 ASE 上要連結 Storage,竟然失敗了

[Azure] Microsoft Azure Storage Explorer-2

發現在建立 ASE 建立連線時,以為只要有存取金鑰就可以存取,把 Account Name 想成是別名,可以隨便取,把 Account Name 修正就可以正常連線

[Azure] Microsoft Azure Storage Explorer-3

一整個烏龍,Orz

星期四, 11月 03, 2016

Win10 上執行 16bit 應用程式

公司製程保全先生跑來詢問,一如往常的一貫語氣,程式在 Win7 32bit 上跑都沒有問題,換成 Win10 64bit 後就不能跑了啦,^^''

原想說,那就相容性模式設一設就好啦,也教過好幾次啦,沒想到這次真的連相容性模式都 GG 了,完全無法執行,畫面如下

Win10 上執行 16bit 應用程式-1

上述錯誤訊息實在是太籠統,在 cmd 內用系統管理者權限去執行,總算是有點線索,不過也囧了,X 的,竟然是 16bit 應用程式

Win10 上執行 16bit 應用程式-2

Google 些資料後發現,原來 Win10 64bit 沒有辦法執行 16bit 應用程式,但是 Win10 32bit 配合 NTVDM 是可以的,馬上利用 Hyper-V 弄個 Win10 32bit 來測試,當執行該程式時,會跳下面訊息,詢問是否要開啟 NTVDM

Win10 上執行 16bit 應用程式-3

安裝完成後就可以開啟該 16bit 應用程式

Win10 上執行 16bit 應用程式-4

目前解決方向
  • 利用 Hyper-V 來安裝 32bit 環境使用
  • 該工程人員還有配一台 XP NB,方便拿到現場機台旁進行操作,16bit 應用程式以後就在該 NB 上執行就好
  • 重灌成 Win10 32bit
想也知道一定是我當苦力,重灌成 Win10 32bit,誰叫你要改成 Win10 64bit 害我不能用,結案,QQ