根據這篇 MSDN 文章 逐步解說:在元件設計工具中建立 Windows 服務應用程式 的筆記,該文章是利用 Windows Service 的啟動、停止和 Timer 來對事件檢視器新增資料,藉此觀察 Windows Service 狀態
在 VS 2015 上建立 Windows Service 範本,路徑是 [Visucal C# => 傳統桌面 => Windows 服務],一開始要找到該範本就卡關,利用 "Windows Service" 去搜尋,完全找不到,以為要在 VS 上另外安裝,Google 後才恍然大悟,中文版應該用 "Windows 服務" 去找才對啦,Orz
星期一, 11月 28, 2016
星期三, 11月 16, 2016
[C#] Control.Visible 和 DataBinding
實務上有把控件隱藏起來的設計,使用時發現資料無法回傳 DB,才發現原來原來控件隱藏的時間點很重要
簡易範例來記錄
Form Layout
- 控件加入 Form 前隱藏,DataBinding 無法正常作動
- 控件加入 Form 後隱藏,預期效果
簡易範例來記錄
Form Layout
星期六, 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 資料
方案內容
WinForm Layout
簡易範例:利用自訂 ComboBox 控件來正確顯示 DropDownList 資料
方案內容
WinForm Layout
星期四, 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); } } }
- 參考資料
- 論壇討論
星期三, 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";
}
}
}
星期二, 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}");
}
}
}
星期一, 11月 07, 2016
[C#] ComboBox DropDownList
使用 ComboBox.DropDownList 時,發現會無法正確地顯示資料,還不是每一個 ComboBox 都會發生,後來釐清才發現,原來設定 DropDownList 時,Item 和 DataBinding 的資料,字元長度要一樣才行
簡易範例 - cboShow 用來顯示使用者 cboSelected 和 chkEmpty 組合資料,完全一模一樣就會顯示在 cboShow 上
簡易範例 - 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;
}
}
}
星期日, 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 來操作看看
沒想到在 ASE 上要連結 Storage,竟然失敗了
發現在建立 ASE 建立連線時,以為只要有存取金鑰就可以存取,把 Account Name 想成是別名,可以隨便取,把 Account Name 修正就可以正常連線
一整個烏龍,Orz
建立 Storage Account 要透過 ASE 來操作看看
沒想到在 ASE 上要連結 Storage,竟然失敗了
發現在建立 ASE 建立連線時,以為只要有存取金鑰就可以存取,把 Account Name 想成是別名,可以隨便取,把 Account Name 修正就可以正常連線
一整個烏龍,Orz
星期四, 11月 03, 2016
Win10 上執行 16bit 應用程式
公司製程保全先生跑來詢問,一如往常的一貫語氣,程式在 Win7 32bit 上跑都沒有問題,換成 Win10 64bit 後就不能跑了啦,^^''
原想說,那就相容性模式設一設就好啦,也教過好幾次啦,沒想到這次真的連相容性模式都 GG 了,完全無法執行,畫面如下
上述錯誤訊息實在是太籠統,在 cmd 內用系統管理者權限去執行,總算是有點線索,不過也囧了,X 的,竟然是 16bit 應用程式
Google 些資料後發現,原來 Win10 64bit 沒有辦法執行 16bit 應用程式,但是 Win10 32bit 配合 NTVDM 是可以的,馬上利用 Hyper-V 弄個 Win10 32bit 來測試,當執行該程式時,會跳下面訊息,詢問是否要開啟 NTVDM
安裝完成後就可以開啟該 16bit 應用程式
目前解決方向
原想說,那就相容性模式設一設就好啦,也教過好幾次啦,沒想到這次真的連相容性模式都 GG 了,完全無法執行,畫面如下
上述錯誤訊息實在是太籠統,在 cmd 內用系統管理者權限去執行,總算是有點線索,不過也囧了,X 的,竟然是 16bit 應用程式
Google 些資料後發現,原來 Win10 64bit 沒有辦法執行 16bit 應用程式,但是 Win10 32bit 配合 NTVDM 是可以的,馬上利用 Hyper-V 弄個 Win10 32bit 來測試,當執行該程式時,會跳下面訊息,詢問是否要開啟 NTVDM
安裝完成後就可以開啟該 16bit 應用程式
目前解決方向
- 利用 Hyper-V 來安裝 32bit 環境使用
- 該工程人員還有配一台 XP NB,方便拿到現場機台旁進行操作,16bit 應用程式以後就在該 NB 上執行就好
- 重灌成 Win10 32bit
- 參考資料
- 電腦出現「已封鎖此應用程式以提供保護」、無法安裝軟體怎麼辦?
- How to Make Old Programs Work on Windows 10
- 網路討論
- StackOverFlow 討論 => 好像可以用外掛方式可以在 64bit 上跑 16bit 應用程式,未測試