none
Formのインスタンスの取得 RRS feed

  • 質問

  • こんにちは。

    C#の初心者です。タイトルのことで質問があります。

     

       //メインフォーム
        public partial class Main : Form
        {
            public Main()


            internal void Specified_line_main(int line_end)
            {
                //処理
            }

        }

        //ダイアログフォーム

        public partial class Junp : Form
        {

            private void OK_Click(object sender, EventArgs e)
            {
                Main.Specified_line_main((int)NumericUpDown1.Value);
                this.Close();
            }

      }

     

    これは、メインフォームからダイアログフォームを表示してOKボタンが押されたらメインフォームのほうに

    ダイアログフォームのほうのNumericUpDownから取得した数値を送ってメインフォームのほうで処理をしようとしているものです。

     

    ところが Main.Specified_line_main((int)NumericUpDown1.Value); のところで

    「静的でないフィールド、メソッド、またはプロパティ 'WindowsFormsApplication1.Main.Specified_line_main(int)' で、オブジェク参照が必要です 」

    とエラーが出ます。

     

    調べてみたところ  Main.Specified_line_main ではなく インスタンス.Specified_line_mainと指定しなければならないようなのですがスタートアップフォームのためインスタンスが取得できなくて困ってます。

     

    ご存じの方よろしくお願いします。

    2008年11月2日 8:55

回答

  • この手の場合はイベントを使った方が良いかと思います。

    もしくはJunpFormがモーダルダイアログ(ShowDialogしている)場合は、JumpForm側にプロパティを作る形でも良いかもしれません。

     

    http://dobon.net/vb/dotnet/vb2cs/event.html

     

    Mainフォーム側でJunpフォームのイベントにイベントハンドラを登録して、JunpフォームではOKボタンが押されたときにイベントを呼び出し、Mainフォーム側のコードを実行するという流れになります。

     

    Code Snippet

    public partial class JumpForm : Form
    {
        public JumpForm()
        {
            InitializeComponent();
        }

        public event EventHandler<IntEventArgs> FormClosedWithValue;

        private void buttonOK_Click(object sender, EventArgs e)
        {
            if (FormClosedWithValue != null)
            {
                FormClosedWithValue(this, new IntEventArgs(100));
            }
            Close();
        }
    }

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private JumpForm _jumpForm;
        private void button1_Click(object sender, EventArgs e)
        {
            _jumpForm = new JumpForm();
            _jumpForm.FormClosedWithValue += new EventHandler<IntEventArgs>(_jumpForm_FormClosedWithValue);
        }

        void _jumpForm_FormClosedWithValue(object sender, IntEventArgs e)
        {
            int returnValue = e.Value; // 戻ってきた値
        }
    }

    class IntEventArgs : EventArgs
    {
        private int _value;
        public IntEventArgs(int value)
        {
            _value = value;
        }
        public int Value
        {
            get { return _value; }
        }
    }

     

     

    2008年11月2日 9:57
    モデレータ
  •  kassyi さんからの引用

    プロパティを使ってやる方法も検討しましたがその場合ループで待機する方法でしか思いつかず

    その場合だとCPUにかなりの負荷がかかってしまうため断念しました。

    ShowDialogメソッドでフォームを表示すると、フォームが閉じられるまでその後のコードが実行されません。

    ※注:この表現は正確ではありません。実際にはタイマーイベントが起きる等、色々と処理されます。

     

    下記のような形で、DialogResultプロパティとは別にプロパティを用意すれば、値を返すことができます。

    http://dobon.net/vb/dotnet/form/okcancelbutton.html

     

    但し、モードレスに(両方のフォームが同時に操作できるように)したいという目的であれば、ShowDialog・プロパティの方法は使えません。

    2008年11月2日 12:36
    モデレータ

すべての返信

  •  kassyi さんからの引用

    ところが Main.Specified_line_main((int)NumericUpDown1.Value); のところで

    「静的でないフィールド、メソッド、またはプロパティ 'WindowsFormsApplication1.Main.Specified_line_main(int)' で、オブジェク参照が必要です 」

    とエラーが出ます。

     

    内容が良く分かってないので的外れな回答かもしれませんが、エラーメッセージに従って

    メソッドを静的 (static) にできないのでしょうか?

    2008年11月2日 9:36
  • この手の場合はイベントを使った方が良いかと思います。

    もしくはJunpFormがモーダルダイアログ(ShowDialogしている)場合は、JumpForm側にプロパティを作る形でも良いかもしれません。

     

    http://dobon.net/vb/dotnet/vb2cs/event.html

     

    Mainフォーム側でJunpフォームのイベントにイベントハンドラを登録して、JunpフォームではOKボタンが押されたときにイベントを呼び出し、Mainフォーム側のコードを実行するという流れになります。

     

    Code Snippet

    public partial class JumpForm : Form
    {
        public JumpForm()
        {
            InitializeComponent();
        }

        public event EventHandler<IntEventArgs> FormClosedWithValue;

        private void buttonOK_Click(object sender, EventArgs e)
        {
            if (FormClosedWithValue != null)
            {
                FormClosedWithValue(this, new IntEventArgs(100));
            }
            Close();
        }
    }

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private JumpForm _jumpForm;
        private void button1_Click(object sender, EventArgs e)
        {
            _jumpForm = new JumpForm();
            _jumpForm.FormClosedWithValue += new EventHandler<IntEventArgs>(_jumpForm_FormClosedWithValue);
        }

        void _jumpForm_FormClosedWithValue(object sender, IntEventArgs e)
        {
            int returnValue = e.Value; // 戻ってきた値
        }
    }

    class IntEventArgs : EventArgs
    {
        private int _value;
        public IntEventArgs(int value)
        {
            _value = value;
        }
        public int Value
        {
            get { return _value; }
        }
    }

     

     

    2008年11月2日 9:57
    モデレータ
  • 回答ありがとうございます。

     

    わかりにくいとのことなのでメインフォームほうの処理の全容を載せます

     

    //「行を指定して移動」 ダイアログ表示後OKが押された場合の処理

    internal void Specified_line_main(int line_end)
     {
                int line_count = 1;
                int char_pos = 0;
                while (line_count < line_end)
                {
                    try { if (TextF.Text[char_pos++] == '\n') line_count++; }
                    catch { break; }  // 指定行が存在しない場合の対策
                }
                TextF.Focus();
                TextF.SelectionStart = char_pos;  // カーソル位置を設定
                TextF.ScrollToCaret();            // カーソルが見える位置までスクロール
            }

    中身は「緑のバイク」というサイトさんからのコピペです。

     

    これに、staticを付けると今度は

    「 静的でないフィールド、メソッド、またはプロパティ 'WindowsFormsApplication1.Main.TextF' で、オブジェクト参照が必要です 」

    と出てしまいます。これについても、調べてみたのですが、thisを付けるとかつけないとかなんかもうわからなくなってしまっています。

     

     

     


     

     

    2008年11月2日 10:11
  • Azuleanさん、ありがとうございました。なるほど、イベントはこのようにして使うのですね。

    プロパティを使ってやる方法も検討しましたがその場合ループで待機する方法でしか思いつかず

    その場合だとCPUにかなりの負荷がかかってしまうため断念しました。

     

    毎回おまじないのように書かれていた「e」の正体も少しだけわかった気がしました。

    SurferOnWww さんもわざわざ回答していただいてありがとうございました。

     

    このサンプルを参考にして何とか実装したいと思います。

     

    またお世話になることがあるかもしれませんが、どうぞよろしくお願いします。

    2008年11月2日 10:36
  •  kassyi さんからの引用

    プロパティを使ってやる方法も検討しましたがその場合ループで待機する方法でしか思いつかず

    その場合だとCPUにかなりの負荷がかかってしまうため断念しました。

    ShowDialogメソッドでフォームを表示すると、フォームが閉じられるまでその後のコードが実行されません。

    ※注:この表現は正確ではありません。実際にはタイマーイベントが起きる等、色々と処理されます。

     

    下記のような形で、DialogResultプロパティとは別にプロパティを用意すれば、値を返すことができます。

    http://dobon.net/vb/dotnet/form/okcancelbutton.html

     

    但し、モードレスに(両方のフォームが同時に操作できるように)したいという目的であれば、ShowDialog・プロパティの方法は使えません。

    2008年11月2日 12:36
    モデレータ
  • なるほど、ShowDialogをつかうとCloseするまでストップするわけですね。

    これははじめて知りました。このことも頭に入れてこれから勉強していきます。

     

    ありがとうございました。

    2008年11月4日 4:16