LastUpdate: 2024/11/20 14:39:14
戻る
プログラミング言語入門 C#
http://school.topposystem.co.jp/CS/Index.asp
テキストボックスや、コマンドボタンなど、標準のコントロールを拡張したコントロールを作ってみる
プロパテイをイベントタブに切り替えて、そこから、メソッド名を選ぶようだ。
つまり、イベントとメソッドを自由に結びつける事ができるみたい。
イベントアクションの所を、ダブルクリックすると、規定値のメソッド名が埋め込まれるようだ。
シールド と読む。これ以上継承不可なこと。Javaでいう、Finaliseの事
ms-help://MS.VSCC.v90/MS.msdnexpress.v90.ja/dv_csref/html/8e4ed5d3-10be-47db-9488-0da2008e6f3f.htm
必要なクラスを記述した、ドロップダウンを表示すると、良い。
下記のように追加される。
参考
自動コード生成
http://msdn2.microsoft.com/ja-jp/library/cdbwbc30.aspx
this.Close();
とすれば、良い。内部で、Disposeメソッドが呼び出される。← 未検証???
また、FormClosing 、 FormClosed イベントが発生する。
textBox1.ReadOnly = checkBox1.Checked;
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void checkBox1_CheckedChanged(object sender, EventArgs e) { textBox1.ReadOnly = checkBox1.Checked; } private void checkBox2_CheckedChanged(object sender, EventArgs e) { textBox1.Enabled = checkBox2.Checked; } private void Form1_Load(object sender, EventArgs e) { textBox1.ReadOnly = checkBox1.Checked; textBox1.Enabled = checkBox2.Checked; } }
入力可能なテキストボックス
表示のみのテキストボックス
無効なテキストボックス
VB で いうところの isDate に相当するもの
DateTime dateTime; if (DateTime.TryParse( inputDate.Text, out dateTime)) { //変換できた時の処理 }
VB で いうところの isNumeric に相当するもの
uint uintResult; if (! uint.TryParse(inputSyohinCode.Text, out uintResult)) { MessageBox.Show("商品コードが数字ではない"); e.Cancel = true; return; }
20080311 ロストフォーカスチェックと最終チェックの実装方法の考察
A.CompareTo(B) とあった場合
A > B の時は、0よりも大きな 値となる
A < B の時は、0よりも小さな 値となる
これが、覚えにくい!
そこで、 A - B と 覚えましょう。
3.CompareTo(1) は 3 - 1 = 2 となり、0よりも 大きな値が返却される事になります。
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_016/csharp_abc01.html
class Program { static void Main(string[] args) { System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection(); //接続文字列を設定 cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0 ; " + "Data Source=C:\\Documents and Settings\\sp0058\\My Documents\\Visual Studio 2008\\testdb1.mdb;"; try { //DBへ接続する cn.Open(); //接続状態を見る Console.Out.WriteLine(cn.State); System.Data.OleDb.OleDbCommand com = new System.Data.OleDb.OleDbCommand("select * from tbl_test1",cn); System.Data.OleDb.OleDbDataReader reader = com.ExecuteReader(); while (reader.Read()) { Console.Out.Write(reader.GetString(0)); Console.Out.Write(reader.GetString(1)); Console.Out.WriteLine(reader.GetString(2)); } //DBへの接続を閉じる cn.Close(); } catch (Exception ex) { Console.Out.WriteLine(ex.Message); } } }
できた事はできたけど、readerから 値を取得するときに、GetString(0) などと、列数で指定するのは ちょっとなぁ〜
他のページを見ていたら、名前で取得する方法も載っていた。
Console.Out.Write(reader["key1"]); Console.Out.Write(reader["data1"]); Console.Out.WriteLine(reader["data2"]);
インデクサ?っていうの? こんな感じで取得できるようだ。
http://www.atmarkit.co.jp/fdotnet/basics/adonet02/adonet02_02.html
教則本に載っていたのをベースに作ってみる
class Program { static void Main(string[] args) { System.Data.OleDb.OleDbConnection cn = new System.Data.OleDb.OleDbConnection(); //接続文字列を設定 cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0 ; " + "Data Source=C:\\Documents and Settings\\sp0058\\My Documents\\Visual Studio 2008\\testdb1.mdb;"; try { //接続状態を見る Console.Out.WriteLine(cn.State); System.Data.OleDb.OleDbDataAdapter adapter = new System.Data.OleDb.OleDbDataAdapter("select * from tbl_test1", cn); System.Data.DataSet testDataSet = new System.Data.DataSet("test"); adapter.Fill(testDataSet, "test"); System.Data.DataTable testDataTable = testDataSet.Tables["test"]; for (int i = 0; i < testDataTable.Rows.Count; i++) { Console.Out.Write(testDataTable.Rows[i][0]); Console.Out.Write(testDataTable.Rows[i][1]); Console.Out.WriteLine(testDataTable.Rows[i][2]); } } catch (Exception ex) { Console.Out.WriteLine(ex.Message); } } }
なんと、DbConnection の Open/Close をしていない!
testDataTable.Rows[i][0] となっているのがなぁ〜。データセットとか、データテーブル とかを、もっと掘り下げてみる必要がありそうだ。
http://www.atmarkit.co.jp/fdotnet/basics/adonet_index/index.html
http://www.atmarkit.co.jp/fdotnet/basics/adonet04/adonet04_01.html
http://www.atmarkit.co.jp/fdotnet/vblab/vsdbprog_01/vsdbprog_01_01.html を参考にしながら、やってみる。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=33576&forum=7
スコープの話
アクセス修飾子 | 説明 |
public | アクセスの制限はありません。 |
protected | アクセスは、クラス内、またはクラスから派生した子クラス内に制限されます。 |
internal | アクセスは現在のアセンブリに制限されます。 |
protected internal | アクセスは、現在のアセンブリ、またはクラスから派生した子クラス内に制限されます。 |
private | アクセスはクラス内に制限されます。 |
{ } | アクセスは、中カッコ内に制限されます。 |
.NETの名前空間と、JAVAのパッケージは異なる。
JAVAのパッケージは、アクセス制限子により、完全ガードをかける事ができるが、名前空間はクラスなどの修飾子やグルーピングには使用できてもアクセス制限ができない事である。
逆に、javaでは、JARアーカイブによるスコープ制限はできないが、.netではアセンブリによるスコープ制限が可能となっている。
種類 | 取りうる値 太字は規定値 |
名前空間内のメンバ (クラス、enum、interface、struct) |
public , internal |
enum内のメンバ | public |
class内のメンバ (プロパティ、メソッド) |
public , internal, private , protected internal |
interface内のメンバ | public |
struct内のメンバ | public , internal, private |
アクセシビリティ レベル
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfDeclaredAccessibilityPG.asp
for文のindexについて
for(int i=0 ; i < 10 ; ++i )
{ ... }
この場合の i は for文の中のみ有効である。
参考
アクセス修飾子 - C# プログラミング ガイド | Microsoft Learn
少ない型数の名前空間を作成しないでください
http://msdn2.microsoft.com/ja-jp/library/ms182130.aspx
言語の比較
http://msdn2.microsoft.com/ja-jp/library/zwkz3536(VS.80).aspx
http://www.ne.jp/asahi/hishidama/home/tech/lang/index.html
.NETでは、Javadocのような機能が2種類用意されている。
APIヘルプとXMLドキュメントである。
APIヘルプは、VSのツールメニューから呼び出せるらしいが、自分が使っているVSでは、表示されない。
どうも、Express版ではAPIは使用できないらしい。
しかし、XMLドキュメントから NDoc というツールで、かなりイケテルドキュメントが生成できるとの事。
http://vsug.jp/tabid/63/forumid/42/threadid/2075/scope/posts/Default.aspx
ところが、NDoc、Framework2.0に正式に対応しなかったらしく、今は Sandcastle という マイクロソフトが提供している同様なソフトがあるらしい。
http://d.hatena.ne.jp/keyword/Sandcastle
値型( = 構造体型)は、値のコピーが行われている。
参照型は、参照渡しされている。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int arg1 = 12; TestData testData = new TestData(); testData.value = 500; string s = "aaa"; testMethod(arg1, testData,s); Console.WriteLine("arg1={0}", arg1); Console.WriteLine("testData.value={0}", testData.value); Console.WriteLine("s={0}", s); } static void testMethod(int arg1, TestData testData,string s) { arg1 = 13; testData.value = 512; s = "bbb"; } } class TestData { public int value; } }
arg1はint型、つまり構造体型なので12のまま。
sはstring型、つまり構造体型なので"aaa"のまま。
testData.valueはクラス、つまり参照型なので512に書きかわっている。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int arg1 = 12;
TestData testData = new TestData();
testData.value = 500;
string s = "aaa";
testMethod(out arg1, testData, out s);
Console.WriteLine("arg1={0}", arg1);
Console.WriteLine("testData.value={0}", testData.value);
Console.WriteLine("s={0}", s);
}
static void testMethod(out int arg1, TestData testData, out string s)
{
arg1 = 13;
testData.value = 512;
s = "bbb";
}
}
class TestData {
public int value;
}
}
outを適用すると、参照渡しになるので、引数の値を変更する事が可能となる。
C#の場合は、引数が変更される可能性がある事を、呼び元でも意識させる必要があるので、
呼び元でも、out句を宣言する事が必要である事に注意
out と ref
参照渡しをする場合には、out句の他に ref句を用いる事もできる。違いは以下の通り。
呼び元 | 呼ばれた先 | |
out | 実体が指し示されていなくても良い。初期化されていなくても良い。 | 値を設定しなくてはならない 出力を強要する。 |
ref | 実体が指し示されている必要あり。初期化されている必要あり。 | 設定は、任意 |
つまり、out句は、出力の為の引数である事を示す事が目的である。
もともと参照型であるクラスインスタンスをout句で呼び出した場合は、呼ばれた先で、インスタンスIDの設定/変更が強制される。インスタンスID内部のパラメタの値では無い事に注意
refは参照型オブジェクトの中のメンバを変更するのではなく、参照型オブジェクトそのものを変更するかもしれない時に用いるものである。
C# プログラマーズ リファレンス out
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/csref/html/vclrfout.asp
基本形
string errorString = string.Format("ERROR CODE = [{0}]", 123);
errorString は "ERROR CODE = [123]" と なる。
取得する対象の関数に、SetLastError=true をつけておく。
[DllImport("KERNEL32.DLL",SetLastError=true, EntryPoint = "WritePrivateProfileString")] private static extern uint DllWritePrivateProfileString( string lpAppName, string lpKeyName, string lpString, string lpFileName);
取得する時は、GetLastError ではなく Marshal.GetLastWin32Error() を 用いる。
http://blog.tbl.jp/2007/10/cwin32apigetlasterror.html
Win32エラーコード一覧
http://ir9.jp/prog/ayu/win32err.htm
習作として、iniファイルを読み書きするクラスを作成してみた。
部分型定義 の事である。つまり、ひとつのクラスを、複数のファイルで別けて定義する事。
利点
- 公開用のメンバ関連と非公開用のメンバ関連を分割することで、クラスの利用者に対して先行して公開することができます。
- 大型プロジェクトを開発する際に、クラスを別個のファイルに分割すると、複数のプログラマが同時にそのクラスの作業を行うことができます。
- 自動生成ソースを使用する際に、ソース ファイルを再作成せずにコードをクラスに追加できます。Visual Studio では、Windows フォームや Web サービス ラッパー コードを作成するときにこのアプローチを使用します。Visual Studio によって作成されたファイルを編集せずに、これらのクラスを使用するコードを作成できます。
http://school.topposystem.co.jp/CS/CS-23.asp
以下の方法でできる
既に、フォーマットされてしまっているコードを、後から再設定したい場合は、貼り付け直しをした際に、オートフォーマットが有効ならば、カット&ペーストで OK
VS2008の場合は、以下の方法しか、無いのかな〜
プロジェクトのプロパティを開く
スタートアップオブジェクトが、Program となっているので、それを、開いてみる。
Programクラスの Mainメソッドで、Form1 と指定されているのを、最初に起動させたいフォームに変更する。
ms-help://MS.VSCC.v90/MS.msdnexpress.v90.ja/dv_raddata/html/4159e815-d430-4ad0-a234-e4125fcbef18.htm
処理の一時停止、スリープ sleep
3秒停止の場合
System.Threading.
Thread.Sleep(3000);//メッセージキューに現在あるWindowsメッセージをすべて処理する
System.Windows.Forms.Application.DoEvents();
http://dobon.net/vb/dotnet/vb6/doevents.html
ある一定期間だけインスタンスのライフサイクルをコントロールしたいとするならば…。
using 句を用いて、コントロールすると良い。
private void button1_Click(object sender, EventArgs e) {
using (LifeCycleTest lifeCycle = new LifeCycleTest()) {
#region 何らかの処理
#endregion
}
}class LifeCycleTest : IDisposable {
/// <summary>
/// コンストラクタ
/// </summary>
public LifeCycleTest() {
System.Console.WriteLine("LifeCycleTest コンストラクタ");
}
#region IDisposable メンバ
public void Dispose() {
System.Console.WriteLine("LifeCycleTest Dispose");
}
#endregion
/// <summary>
/// ディストラクタ
/// </summary>
~LifeCycleTest() {
System.Console.WriteLine("LifeCycleTest ディストラクタ");
}
}
using で スコープを抜ける時、Disposeメソッドを呼び出すカラクリになっている。つまり、System.IDisposable インターフェイス型である(インターフェイスを実装している)必要がある。
System.IDisposable インターフェイス型でない場合は、コンパイルエラーとなるusing ステートメントで使用される型は、暗黙的に 'System.IDisposable' への変換が可能でなければなりません。
上記の例では、明示的にディストラクタを実装してみたが、ディストラクタが呼び出されるのは、メモリから破棄されるタイミングである。
このタイミングは、ガベージコレクションに依存する。つまりDisposeが呼び出されても、ディストラクタが何時行われるかは制御できない。Disposeは、「不要となった」事をマーキングさせる為の機能と解釈するのが良いと思われる。
参考
http://www.atmarkit.co.jp/fdotnet/easyvs/easyvs03/easyvs03_06.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/027dispose/dispose.html
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_011/cs2_011_03.html
たとえば、ボタン1のクリックイベントが発生した場合、複数のイベントハンドラーを呼び出したいというニーズがあった時に、対応する事ができます。
public partial class Form3 : Form {
public Form3() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
System.Console.WriteLine("普通のボタン1クリックイベント");
}
// 追加するイベントリスナー
private void AddEvent(object sender, EventArgs e) {
System.Console.WriteLine("追加のイベント");
}
private void Form3_Load(object sender, EventArgs e) {
// ボタン1クリックイベントに、イベントリスナーを追加する
this.button1.Click += new System.EventHandler(this.AddEvent);
}
private void Form3_FormClosed(object sender, FormClosedEventArgs e) {
// ボタン1クリックイベントから、イベントリスナーを削除する
this.button1.Click -= new System.EventHandler(this.AddEvent);
}
}
イベントリスナーを追加する時は += は 理解できるんだけど、
削除する時に、 -= new … っていうのは 理解しにくい構文です。
実行すると、
普通のボタン1クリックイベント
追加のイベント
のように表示されます。
ボタンクリック処理で処理時間がかかる際、マウスカーソルを砂時計にする…というのはよくあるニーズだが、処理が終わった際にはマウスカーソルを初期値に戻したいわけで。出口処理が複数有った時に、それぞれでマウスカーソルを初期値に戻すのは、かっこわるい。
VC++の頃は、ローカル変数のディストラクタが明示的に走る事を利用して、マウスカーソルを自動的に初期化するような便利なクラスがあったが、ガーベジコレクションする.NETで、同様な事ができないか〜と思い、考えてみた。
20080409_イベントハンドラーの追加と削除 の機能を使えば、似たような事はできるのでは…との思いから、チャレンジしてみる事にした。
が!
コマンドボタンの2度押し防止の事を合わせて検討する必要に発生したため、合わせて 検討してみる事にした。
詳細はココで 処理中マウスカーソルと2度押し防止について
.NET における例外管理
http://www.microsoft.com/japan/msdn/net/bda/exceptdotnet.aspx
自分で例外を作成する時は、ApplicationException を継承すべし…最近は、推奨されてない?
http://shinshu.fm/MHz/95.83/archives/0000127004.html
1.x系の時はApplicationException を継承すべしだったそうだが、
2.x系の時は、Exceptionで良いとの事
Javaにある検査例外は、.NETには無い
既存の例外の一覧が見やすいページ
http://msdn2.microsoft.com/ja-jp/library/system.exception.aspx
簡単に出力ウィンドーにデバッグ内容を表示したいときは、
とすれば良い。
お勉強を兼ねて、1から作ってみる。
フォームオブジェクト版
お勉強を兼ねて、1から作ってみる。https://qiita.com/YouKnow/items/d6823afa7f676f309340
ようするに、関数ポインタの配列を持つクラス。
【C# Delegate, Func】別の関数を引数とした関数作成 #C# - Qiita
【C#】delegate, Action, Funcについて 多分一番易しい解説 │ FPGA完全に理解した
https://ittrip.xyz/c-sharp/csharp-thread-2