0

c# で windowsFrom を使用しています。ユーザーコントロールのいずれかで mainfrom メソッドを呼び出そうとしています。私はこのようなmainfromを持っています

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

    public void TempCommand()
      {
       StartTemp();
      }
   }
 }

ユーザーコントロールでボタンをクリックします。そのボタンをクリックすると、別のフォームが開きます。ユーザーコントロールにこのようなコードがあります。

   private TempCalib _tempCalib = new TempCalib();

   private void calibBtn_Click(object sender, EventArgs e)
    {
        _tempCalib.Show();
    }

それは別のから開きます。その中にボタンが1つあります。このfromで「OK」ボタンをクリックすると、mainfromメソッドを呼び出す必要があります。

namespace Project
{
public partial class TempCalib : Form
{

    public TempCalib()
    {
        InitializeComponent();
    }

    private void OkButton_Click(object sender, EventArgs e)
    {
       // I need to call the mainfrom "TempCommand" method here.
        this.Hide();
    }


   }
 }

誰でもこれを行う方法を手伝ってもらえますか。

ありがとう。

4

5 に答える 5

4

素早い回答

セカンダリ フォームにプライマリ フォームへの参照を追加するだけです。

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を再利用でき、デザイナーにとってより使いやすくなります)。フォームを作成し、適切な型にキャストします)。TempCalibUserControlFormUserControl

改良点

この種の参照は、多くの場合、アラートです。通常、UI コンポーネントはそれほど結合されるべきではなく、 publicFormのメソッドが非常に頻繁に何かを実行するのは、 にロジックが多すぎるというシグナルですForm。これを改善するにはどうすればよいですか?

1. デカップルコントロール。最初のステップは、それらを少し切り離すことかもしれません。イベントを追加して、そのレシーバーを作成するだけですTempCalibMainForm

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. ロジックを実装から切り離す。ここでも、実行する手順がさらにあります (必要な場合)。コントローラーはまだ具象型 (および) を認識しています。実行時に別のフォームを選択する必要がある場合 (たとえば、複雑なインターフェイスと単純化されたインターフェイスを使用したり、依存性注入を使用したりする場合)、インターフェイスを使用してコントローラーを分離する必要があります。ほんの一例:MainFormTempCalib

public interface IUiWindow
{
    void Show();
    void Hide();
}

public interface IMainWindow : IUiWindow
{
    event EventHandler Calibrate;
}

public interface ICalibrationWindow : IUiWindow
{
    event EventHandler SomethingMustBeDone;
}
于 2013-07-16T09:08:17.927 に答える
0

Form1 コード:

    UserControl1 myusercontrol = new UserControl1();

    public void TabClose(Object sender,EventArgs e)
    {
        int i = 0;
        i = tabControl1.SelectedIndex;
        tabControl1.TabPages.RemoveAt(i);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        myusercontrol.Dock = DockStyle.Fill;
        TabPage myTabPage = new TabPage();
        myTabPage.Text = "Student";
        myTabPage.Controls.Add(myusercontrol);
        tabControl1.TabPages.Add(myTabPage);
        myusercontrol.OkClick += TabClose;

    }

UserControl1 コード:

     public delegate void OkClickedHandler(Object sender, EventArgs e);

public partial class UserControl1 : UserControl
{

    public event OkClickedHandler OkClick;
    public UserControl1()
    {
        InitializeComponent();

    }


    private void button3_Click(object sender, EventArgs e)
    {
        if (OkClick == null) return;
        OkClick(sender, e);

    }
}
于 2014-07-10T12:08:17.843 に答える
0

ユーザーコントロールでイベントを作成し、メインフォームでこれをサブスクライブします。それが通常の方法です。

于 2013-07-16T09:06:01.493 に答える
0

で宣言されているカスタム イベントを使用できますUserControl。次に、フォームでこのイベントを処理し、呼び出したいメソッドを呼び出す必要があります。にフォームへのUserControlアクセスを許可すると、両方が相互にハードリンクされ、 の再利用性が低下しますUserControl

たとえば、TempCalib次のようになります。

public delegate void OkClickedHandler(object sender, EventArgs e);
public event OkClickedHandler OkClicked;

private void OkButton_Click(object sender, EventArgs e)
{
    // Make sure someone is listening to event
    if (OkClicked == null) return;

    OkClicked(sender, e);

    this.Hide();       
}

あなたのメインフォームで:

private void Mainform_Load(object sender, EventArgs e)
{
    _tempCalib.OkClicked += CalibOkClicked;
}

private void CalibOkClicked(Object sender, EventArgs e)
{
    StartTemp();
}
于 2013-07-16T09:17:14.793 に答える
-1

これを試して:

ユーザーコントロールからこれを試してください:

MainForm form = this.TopLevelControl as MainForm;
form.TempCommand();
于 2013-07-16T09:23:21.017 に答える