トップ回答者
Formのインスタンスの取得

質問
-
こんにちは。
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と指定しなければならないようなのですがスタートアップフォームのためインスタンスが取得できなくて困ってます。
ご存じの方よろしくお願いします。
回答
-
この手の場合はイベントを使った方が良いかと思います。
もしくはJunpFormがモーダルダイアログ(ShowDialogしている)場合は、JumpForm側にプロパティを作る形でも良いかもしれません。
http://dobon.net/vb/dotnet/vb2cs/event.html
Mainフォーム側でJunpフォームのイベントにイベントハンドラを登録して、JunpフォームではOKボタンが押されたときにイベントを呼び出し、Mainフォーム側のコードを実行するという流れになります。
Code Snippetpublic 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; }
}
} -
kassyi さんからの引用 プロパティを使ってやる方法も検討しましたがその場合ループで待機する方法でしか思いつかず
その場合だとCPUにかなりの負荷がかかってしまうため断念しました。
ShowDialogメソッドでフォームを表示すると、フォームが閉じられるまでその後のコードが実行されません。
※注:この表現は正確ではありません。実際にはタイマーイベントが起きる等、色々と処理されます。
下記のような形で、DialogResultプロパティとは別にプロパティを用意すれば、値を返すことができます。
http://dobon.net/vb/dotnet/form/okcancelbutton.html
但し、モードレスに(両方のフォームが同時に操作できるように)したいという目的であれば、ShowDialog・プロパティの方法は使えません。
すべての返信
-
この手の場合はイベントを使った方が良いかと思います。
もしくはJunpFormがモーダルダイアログ(ShowDialogしている)場合は、JumpForm側にプロパティを作る形でも良いかもしれません。
http://dobon.net/vb/dotnet/vb2cs/event.html
Mainフォーム側でJunpフォームのイベントにイベントハンドラを登録して、JunpフォームではOKボタンが押されたときにイベントを呼び出し、Mainフォーム側のコードを実行するという流れになります。
Code Snippetpublic 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; }
}
} -
回答ありがとうございます。
わかりにくいとのことなのでメインフォームほうの処理の全容を載せます
//「行を指定して移動」 ダイアログ表示後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を付けるとかつけないとかなんかもうわからなくなってしまっています。
-
-
kassyi さんからの引用 プロパティを使ってやる方法も検討しましたがその場合ループで待機する方法でしか思いつかず
その場合だとCPUにかなりの負荷がかかってしまうため断念しました。
ShowDialogメソッドでフォームを表示すると、フォームが閉じられるまでその後のコードが実行されません。
※注:この表現は正確ではありません。実際にはタイマーイベントが起きる等、色々と処理されます。
下記のような形で、DialogResultプロパティとは別にプロパティを用意すれば、値を返すことができます。
http://dobon.net/vb/dotnet/form/okcancelbutton.html
但し、モードレスに(両方のフォームが同時に操作できるように)したいという目的であれば、ShowDialog・プロパティの方法は使えません。