mikeo_410


タブページ・アプリケーションの作り方

1.要点

複数のサンプルプログラムを1つの実行形式に入れる方法としてTabPageクラスを使いました。
各タブが1つのFormアプリケーションだと考えていただければと思います。
Formアプリケーションの始まり、終了の処理は、それぞれLoad()、FormClosing()を使いますが、タブアプリケーションではOnEnter()、OnLeave()を使いました。独立したプログラムを作成する場合は、この対応が利用できます。ただし、注意が必要なのは、Enter、Leaveイベントは、必ずしも対で発生するわけではなく、重複して発生することです。サンプルでは、フラグを使って対の関係を保っています。

 2.タブページの追加

サンプルは、TabPageクラスを継承して作ってあります。プログラムは、タブごとに独立しています。デザイナが、直接サポートしないので以下の手順で作りました。(何か良い方法がありそうですが良く分かりません。)

  1. 参照に、このDLLを追加します。
  2. 通常のクラスを追加します。
  3. クラス宣言を、
    public class xxx : TabPage {
    の形に、継承を追加します。
  4. そうすると、「デザイナ」が、開けるようになるので、ChartCtrlコントロールをツールボックスから貼り付けます。
    下図のように、貼り付けたChartCtrlコントロールのプロパティで、DockをFillに設定するとTabPage全体が描画領域になります。
    ForeColor、Font、BackColorも変更できます。
  5. この操作で、
    private ChartCtrl.ChartCtrl chartCtrl1;
    private IContainer component;
    private void InitializeComponent()
    {
    }
    のような、コントロールの初期化が追加されます。ただし、このメソッドは、呼び出す部分がありません。また、コントロール間の関連を追加する部分もありません。
  6. そこで、コンストラクタを追加して、InitializeComponent()を呼び出すようにします。
  7. コントロール間の関連を付けるためのメソッドを追加します。
    public void Initialize()
    {
                this.Controls.Add(this.chartCtrl1);
    }
  8. Formには、TabControlを貼り付けておきます。
    自動的に、2つのタブページが追加されますが、右ボタンメニューで削除します。
  9. このメソッドを、FormのLoad()から呼び出します。
    Wave tabPage_wave;
    //------------------------------------------------------------------
    private void Form1_Load(object sender, EventArgs e)
    {
        //タブページを設定
        tabPage_wave = new Wave();
        tabPage_wave.Initialize();
        //タブページを追加
        this.tabControl1.Controls.Add(tabPage_wave);

3.サンプルプログラムの内容

右ボタンメニューから「コードの表示」を選んで、TabPageを継承した、アプリケーションクラスを編集します。

 3.1.コンストラクタの追加

 コントロールを貼り付けることで、デザイナが自動的に
InitializeComponent()
が、作られます。これを、コンストラクタから呼び出すようにします。コンストラクタは、クラスと同じ名前の、戻り値の宣言のない、メソッドです。(下記は、クラス名がWaveの場合)

public Wave()
{
   InitializeComponent();
}

 

3.2.Initialize()の追加

コントロール間の関連は、親のコントロールに、子のコントロールを追加することで表現します。この処理は、基本的に末端から行う必要があります。このクラスが、TabControlに追加される前に行う必要があります。このために、FormのLoad()から呼び出す処理としてInitialize()を追加します。名前は、決まっているわけではありません。

public void Initialize()
{
   bDone = true;
   this.Controls.Add(this.chartCtrl1);
}

 

この処理で、ChartCtrlが、このTabPageに追加されます。
bDoneは、このアプリケーションで使っているループ脱出用のループ型のフラグです。Enter()、Leave()の多重処理の防止にも使っています。

3.3.Form1の変更

Form1には、あらかじめ、TabControlを貼っておきます。自動的に2つのタブが追加されますが、削除します。
Load()のタイミングで、タブページを作成、初期化し、TabControlに追加します。

Wave tabPage_wave;

private void Form1_Load(object sender, EventArgs e)
{
    //タブページを設定
    tabPage_wave = new Wave();
    tabPage_wave.Initialize();
    :
    //タブページを追加
    this.tabControl1.Controls.Add(tabPage_wave);
    :
    //最初のページを選択
    this.tabControl1.SelectedIndex = -1;
    this.tabControl1.SelectTab(tabPage_wave);
}

 

3.4.タブページアプリケーションの開始

タブが選択されたときの処理をOnEnter()に記述します。
ソースコードのメソッドの記述可能箇所で、overrideと入力すると、インテリセンスが機能して一覧が表示されます。ここで、OnEnterを選択すると自動的にメソッドが追加されます。
ここでは、PCMの入力処理の準備、軸等の描画をしています。
 

protected override void OnEnter(EventArgs e)
{
    if (bDone)
    {
        bDone = false;
        //PCM受信の初期化
        inPCM = new InPCM(SAMPLING_RATE, SAMPLE_SIZE);
        //背景色を設定
        chartCtrl1.BackColor = Color.Beige;
        //クライアント領域(横長)の高さを基準に図のデータ部分を決める。
        RectangleF rect = new RectangleF(40, 40, chartCtrl1.ClientSize.Width - 80, chartCtrl1.ClientSize.Height - 80);
        //Xは0 - サンプリング時間、Yは-32768 - 32767の範囲が、rectに対応するように初期化。
        chartCtrl1.BeginDrawing(rect, 0, SAMPLING_TIME, -1, 1);
        //軸を描画
        DrawAxis();
        //終了
        chartCtrl1.EndDrawing();
        //軸の描画内容を退避
        saveMetafile = chartCtrl1.SaveMetafile();
        //インターバルタイマの初期化
        timer1.Interval = 200;
        timer1.Enabled = true;
    }
    base.OnEnter(e);
}

3.5.タブページアプリケーションの終了

別のタブが選ばれた場合には、PCM入力処理を停止します。

protected override void OnLeave(EventArgs e)
{
    if (!bDone)
    {
        timer1.Enabled = false;
        bDone = true;
        inPCM.Close();
        inPCM = null;
        pcm = null;
    }
    base.OnLeave(e);
}

 3.6.タイマーイベントの処理

 ここでは、タイマでPCMデータを受信しています。デザイナで、ツールボックスからタイマーを貼り付けて、貼り付けたタイマをダブルクリックするとメソッドが追加されます。入力したPCMデータは、DrawWave()で波形をリアルタイム表示します。

private void timer1_Tick(object sender, EventArgs e)
{
    while (!bDone)
    {
        int qc = inPCM.GetQueueCount();
        if (qc <= 0) break;
        pcm = inPCM.Read();
        if (qc == 1) DrawWave();
    }
}

 

3.7.入力波形のるあるタイム表示

 OnEnter()の処理で退避していた軸などの描画に、波形を重ねて描画します。

void DrawWave()
{
    double tick = (1000.0 * d) / SAMPLING_RATE;
    double xx = 0.0;
    int j = 0;
    for (int i = 0; i < points.Length; i++)
    {
        points[i].X = (float)xx;
        points[i].Y = (float)((double)pcm[j]/32768.0);
        xx += tick;
        j += d;
    }
    chartCtrl1.ResumeDrawing(saveMetafile);
    chartCtrl1.DrawLines(Pens.DarkRed, points);
    chartCtrl1.EndDrawing();
}

青葉区 不動産 京都 不動産査定 横浜市 不動産 検索エンジン登録 アルパイン