素早い回答
セカンダリ フォームにプライマリ フォームへの参照を追加するだけです。
public partial class TempCalib : Form
{
private MainForm _main
public TempCalib(MainForm main) : this()
{
_main = main;
}
/// Other stuffs
}
次に、セカンダリ フォームを作成するときに値を割り当てます。
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
if (_tempCalib == null)
_tempCalib = new TempCalib(this);
_tempCalib.Show();
}
calibBtn_Click
内部にない場合MainForm
(ただし、その上にある場合)、初期化を次のUserControl
ように置き換えることができます。_tempCalib
_tempCalib = new TempCalib((MainWindow)FindForm());
その後、プライマリ フォームを呼び出すことができます。
private void OkButton_Click(object sender, EventArgs e)
{
_main.TempCommand();
this.Hide();
}
注: これは 1 つのオプションにすぎません。参照を保持するプロパティを作成することができます(二次フォームMainForm
を再利用でき、デザイナーにとってより使いやすくなります)。フォームを作成し、適切な型にキャストします)。TempCalib
UserControl
Form
UserControl
改良点
この種の参照は、多くの場合、アラートです。通常、UI コンポーネントはそれほど結合されるべきではなく、 publicForm
のメソッドが非常に頻繁に何かを実行するのは、 にロジックが多すぎるというシグナルですForm
。これを改善するにはどうすればよいですか?
1. デカップルコントロール。最初のステップは、それらを少し切り離すことかもしれません。イベントを追加して、そのレシーバーを作成するだけですTempCalib
。MainForm
public partial class TempCalib : Form
{
public event EventHandler SomethingMustBeDone;
private void OkButton_Click(object sender, EventArgs e)
{
OnSomethingMustBeDone(EventArgs.Empty); / TO DO
this.Hide();
}
}
次にMainForm
:
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
if (_tempCalib == null)
{
_tempCalib = new TempCalib();
_tempCalib.SomethingMustBeDone += _tempCalib_SomethingMustBeDone;
// In _tempCalib_SomethingMustBeDone you'll invoke proper member
// and possibly hide _tempCalib (remove it from OkButton_Click)
}
_tempCalib.Show();
}
2. コントロールからロジックを分離します。UI はかなり頻繁に変更されますが、ロジックは変更されません (そして、変更されたときは、おそらく UI と並行していません)。これは最初のステップにすぎTempCalib
ません (誰が使用するかはわかりません)。次のステップ (フォーム内で多くのことが発生した場合に実行) は、この種のロジックをフォーム自体から削除することです。少しの例 (非常に生)、TempCalib
以前と同じように (イベントを使用して) 保持し、パッシブMainForm
に変更します。
public partial class MainForm : Form
{
public event EventHandler Calibrate;
protected virtual void OnCalibrate(EventArgs e)
{
// TODO
}
}
次に、フローとロジックを制御するクラスを作成しましょう。
public class MyTaskController
{
private MainForm _main;
private TempCalib _tempCalib;
public void Start()
{
_main = new MainForm();
_main.Calibrate += OnCalibrationRequested;
_main.Show(); // Or whatever else
}
private void OnCalibrationRequested(object sender, EventArgs e)
{
if (_tempCalib == null)
{
_tempCalib = new TempCalib();
_tempCalib.SomethingMustBeDone += OnSomethingMustBeDone();
}
_tempCalib.Show();
}
private OnSomethingMustBeDone(object sender, EventArgs e)
{
// Perform the task here then hide calibration window
_tempCalib.Hide();
}
}
はい、さらに多くのコードを記述する必要がありますが、これにより、UI 自体からロジック(たとえば、アクションへの応答として何を行うか) を切り離すことができます。プログラムが大きくなったとき、これは必要に応じて UI を変更し、ロジックがそれを認識しないようにするのに役立ちます (そして明確に定義された 1 つの場所で)。これにより、さまざまなリソース(人) を使用してロジックと UI を記述できるようになること (または、さまざまな UI、WinForms、WPF などにロジックを再利用できること) については言及しません。とにかく、IMO の最も明白で十分に還元される利点は...読みやすさです。ロジックがどこにあり、UI 管理がどこにあるのかを常に知ることができ、検索も混乱も間違いもありません。
3. ロジックを実装から切り離す。ここでも、実行する手順がさらにあります (必要な場合)。コントローラーはまだ具象型 (および) を認識しています。実行時に別のフォームを選択する必要がある場合 (たとえば、複雑なインターフェイスと単純化されたインターフェイスを使用したり、依存性注入を使用したりする場合)、インターフェイスを使用してコントローラーを分離する必要があります。ほんの一例:MainForm
TempCalib
public interface IUiWindow
{
void Show();
void Hide();
}
public interface IMainWindow : IUiWindow
{
event EventHandler Calibrate;
}
public interface ICalibrationWindow : IUiWindow
{
event EventHandler SomethingMustBeDone;
}