TabPage Chenge

複数ファイルをオープンして Tab Page で切り替えます。

前田稔(Maeda Minoru)の超初心者のプログラム入門

RichTextBox の設定

  1. いよいよ Multi File Editor に挑戦です。
    複数ファイルを同時にオープンして TabControl の Page クリックで切り替えます。
    TabControl と RichTextBox の配置には注意が必要で、予備知識として TabPage のクリック を参照して下さい。
  2. RichTextBox を tabControl とは独立させて Form に直接張り付けるように修正します。
    Single File Editor の Form1.Designer.cs の抜粋です。
    tabPage1 に richTextBox1 が従属して、Size も大きくなっています。
    また richTextBox1 に Dock が設定されています。
    これでは PabPage を切り替えると RichTextBox が表示されません。
        // tabPage1
        this.tabPage1.Controls.Add(this.richTextBox1);
        this.tabPage1.Size = new System.Drawing.Size(768, 342);
        // richTextBox1
        this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.richTextBox1.Location = new System.Drawing.Point(3, 3);
    
  3. 次のように修正して下さい。
    tabPage1 から richTextBox1 を外し、Size を調整します。
    richTextBox1 の Dock を外して、Location と Size を調整します。
    Location と Size は後から調整するので適当で構いません。
    Form1 に直接 RichTextBox を張り付けます。
        // tabPage1
        this.tabPage1.Size = new System.Drawing.Size(768, 0);
        // richTextBox1
        this.richTextBox1.Location = new System.Drawing.Point(20, 120);
        this.richTextBox1.Size = new System.Drawing.Size(800, 200);
        // Form1
        this.Controls.Add(this.richTextBox1);
        this.Controls.Add(this.tabControl1);
    
  4. Form に Resize を追加して RitchTextBox を配置します。
    環境に合わせて数値を調整して下さい。
        this.Resize += new System.EventHandler(this.formResize);
        private void formResize(object sender, EventArgs e)
        {
            richTextBox1.Left = 4;
            richTextBox1.Top = 46;
            richTextBox1.Width = this.Width - 24;
            richTextBox1.Height = this.Height - 90;
        }
    
  5. コンパイル&実行すると、Single File Editor と同様に表示されます。
    設定した効果が表れるのは、複数ファイルを開いたときです。

複数ファイル

  1. 準備が出来た所で、複数のファイルを開いてみましょう。
    複数ファイルの領域定義です。
    m_page で class FileClass の領域を配列で定義します。
    m_num は現在編集中の m_page の Index です。
        ArrayList   m_page;     // 編集ファイルの配列
        int         m_num;      // 現在編集中の m_page(初期値 -1)
    
    Form1 の Constructor で初期化して下さい。
        m_page = new ArrayList();
        m_num = -1;
    
  2. LoadFile メソッドで編集ファイルを読み込みします。
    新しいファイルをロードして FileClass を生成します。
    m_page.Add(m_fclass); で m_fclass を m_page[] に追加します。
    TabControl のページに m_page の Index と一致するようにファイル名を設定します。
    TabControl には最初からページが1個設定されているので注意して下さい。
    m_num に編集ページを設定します。
            private void LoadFile(string tpath, string tcode)
            {
                if (!File.Exists(tpath))
                {
                    Console.WriteLine("File NotFound: " + tpath);
                    return;
                }
                m_szDir = tpath;
                this.Text = m_szDir;
                m_fclass = new FileClass(tpath, tcode);
                m_fclass.ReadFile();
                m_fclass.Load(richTextBox1);
                m_flag = false;
                m_page.Add(m_fclass);
                if (tabControl1.TabPages.Count < m_page.Count)
                {   // TABControl1 にファイル名を追加
                    TabPage tab = new TabPage(m_fclass.file);
                    tabControl1.TabPages.Add(tab);
                }
                else tabControl1.GetControl(m_page.Count - 1).Text = m_fclass.file;
                m_num = m_page.Count - 1;
                tabControl1.SelectTab(m_num);
            }
    
  3. TabControl のプロパティから稲妻アイコンを選択します。
    Selected の右側に "tabSelected" とタイプするとイベントハンドラが作成されます。
    TabPage がクリックされると、該当する TEXT を m_page[] から取得して richTextBox1 に表示します。
            private void tabSelected(object sender, TabControlEventArgs e)
            {
                if (m_page.Count == 0)
                {
                    richTextBox1.Clear();
                    return;
                }
                m_num = e.TabPageIndex;
                if (m_num >= m_page.Count) return;
                m_fclass = (FileClass)m_page[m_num];
                m_fclass.Load(richTextBox1);
            }
    
  4. これで2個目のファイルを開くと RitchTextBox に表示されます。
    同様に3個目, 4個目のファイルを開いてみて下さい。
    また TABControl の TabPage をクリックすると選択された TEXT が表示されます。

Page Jump

  1. Single File Editor では一個のファイルしか開かないのでジャンプはファイル内に限られていました。
    今回は複数のファイルを開くので、F1~F4 キーにファイルと位置を記録して Shift+F1~F4 キーでファイルを超えてジャンプします。
    ファイルと位置を記録するために class FileName を定義します。
    FileName は複数のファイルを登録してメニューから一発でオープンするときにも使います。
    path と code は登録されたファイルを開くときに使用します。
    num が ArrayList m_page の Index で、cursor が現在作業中のカーソル位置です。
        public class FileName
        {   public string   path;       //ファイルパス
            public string   code;       //TEXTコード
            public int      num;        //TabPage 番号
            public int      cursor;     //カーソル位置
    
            // Constructor
            public FileName(string tpath, string tcode, int p)
            {   path = tpath;
                code = tcode;
                cursor = p;
                num = 0;
            }
            public FileName(int n, int p)
            {   path = string.Empty;
                code = string.Empty;
                num = n;
                cursor = p;
            }
        }
    
  2. 現在の編集位置を登録するために m_CurPos を定義します。
    Single File で使っていた int[] m_CurPos = new int[4]; は不要になります。
        FileName[]  m_CurPos = new FileName[4];
    
  3. 現在の編集位置を登録する F1~F4 キーのコーデイングです。
        case Keys.F1:       //F1~F4 カーソル位置を記憶
            m_CurPos[0] = new FileName(m_num, wp);
            break;
        case Keys.F2:
            m_CurPos[1] = new FileName(m_num, wp);
            break;
        case Keys.F3:
            m_CurPos[2] = new FileName(m_num, wp);
            break;
        case Keys.F4:
            m_CurPos[3] = new FileName(m_num, wp);
            break;
    
  4. 登録した[ファイル+位置]にジャンプする Shift+F1~F4 キーのコーデイングです。
        case Keys.F1:   //カーソル位置にジャンプ
            PageChenge(m_CurPos[0].num, m_CurPos[0].cursor);
            break;
        case Keys.F2:
            PageChenge(m_CurPos[1].num, m_CurPos[1].cursor);
            break;
        case Keys.F3:
            PageChenge(m_CurPos[2].num, m_CurPos[2].cursor);
            break;
        case Keys.F4:
            PageChenge(m_CurPos[3].num, m_CurPos[3].cursor);
            break;
    
  5. PageChenge() メソッドです。
    newpage がジャンプ先のページで cursor がその位置です。
    現在編集中のページは m_num に格納されています。
    ページが変わったとき現在のページを m_page[m_num] に退避します。
    新しいページを RichTextBox に設定して cursor に位置付けます。
        private void PageChenge(int newpage, int cursor)
        {
            if (m_page.Count == 0)
            {   richTextBox1.Clear();
                return;
            }
    
            if (newpage!=m_num)     //ページが異なるとき
            {   //現在ページを保存
                if (m_num>=0 && m_num<m_page.Count)
                {
                    m_fclass.Save(richTextBox1);
                    m_fclass.cursor = richTextBox1.SelectionStart;
                    m_page[m_num] = m_fclass;
                }
                //m_page[newpage]をロード
                m_num = newpage;
                if (m_num<0 || m_num>=m_page.Count)   m_num = 0;
                m_fclass = (FileClass)m_page[m_num];
                m_fclass.Load(richTextBox1);
                tabControl1.SelectTab(m_num);
            }
            if (cursor>0)   m_fclass.cursor = cursor;
            this.Text = m_fclass.path;
            SetCurPos(m_fclass.cursor);
        }
    
  6. カーソル位置をページの先頭に表示する SetCurPos() メソッドです。
        private void SetCurPos(int cur)
        {   int pos, wk;
    
            pos = cur;
            if (pos<0)  pos = 0;
            wk = richTextBox1.GetLineFromCharIndex(pos);
            wk = richTextBox1.GetFirstCharIndexFromLine(wk);
            richTextBox1.Select(wk,0);
            richTextBox1.Focus();
            richTextBox1.ScrollToCaret();
        }
    
  7. PageChenge() メソッドを作成したので、tabSelected() でもこれを利用します。
        private void tabSelected(object sender, TabControlEventArgs e)
        {
            if (m_page.Count==0)
            {
                richTextBox1.Clear();
                return;
            }
            if (e.TabPageIndex>=m_page.Count)   return;
            PageChenge(e.TabPageIndex, -1);
        }
    

[Next Chapter ↓] FileClass
[Previous Chapter ↑] Single File Editor

超初心者のプログラム入門(C# Frame Work)