0

アプリを開発しており、アプリに含まれるすべてのフォームで機能するいくつかのボタンなどのグローバル機能を含めたいと考えています。

これは、4 つの子フォームを含む MDI アプリケーションであり、各フォームは異なるタスクを実行し、それぞれに独自のコントロールがあります。各フォームに [クリア] ボタンと [検索] ボタンがあり、現在アクティブなフォームに対してこれらのアクションを実行する 2 つのグローバル ボタンを作成しようとしています。

たとえば、Form1 は MDI の親であり、Form2 は Form1 の子です。Form1 にある ToolStripMenuItem から Form2 を呼び出します。Form2 には、その中のすべてのテキスト ボックスをクリアするボタンがあります。私が達成したいのは、このボタンのコードを Form1 (MDI 親) の一般的なバーに配置されたボタンに移動して、Form2 のテキスト ボックスだけでなく、アプリにあるすべてのフォームをクリアすることです。

これは私がこれまでに得たものです:

//Form1 code
public partial class FrmPrincipal : Form
{
    public FrmPrincipal()
    {
        InitializeComponent();
    }
    private void manageUsersToolStripMenuItem_Click(object sender, EventArgs e) //Calling Form2
    {
        FrmUserManager frmusers = new FrmUserManager();
        frmusers.MdiParent = this;
        frmusers.Show();

    }
}

//Form2 code
public partial class FrmUserManager : Form
{   
    public FrmUserManager()
    {
        InitializeComponent();
    }
}

private void BtnClear_Click(object sender, EventArgs e)
{
    Clear(this);
}

private void Clear(Control all)
{
    foreach (Control all in all.Controls)
    {
        if (all is TextBox) ((TextBox)all).Text = string.Empty;
        if (all is CheckBox) ((CheckBox)all).Checked = false;
        if (all is DataGridView) ((DataGridView)all).DataSource = null;
        if (all.Controls.Count > 0) Clear(all);
    }
}

したがって、基本的には、このコードを Form1 のボタンに移動して、Form2 の外部からこのアクションを実行する必要があります。それができれば、4 つの子フォーム (検索とクリア) にあるボタンを取り除くことができ、さらにアプリが使いやすくなります。

私が考えた唯一の方法は、Form2 の各コントロールのプロパティ「Modifiers」を「public」に変更して、Form1 から次のような方法でアクセスしようとすることです。

Form2 frm2 = new Form2();
if(frm2.Active == true) Clear(this);

この場合、各フォームをインスタンス化し、アクティブかどうかを確認します。

エラーは表示されませんが、それでも機能しません。Form2 を呼び出すために作成されたオブジェクトは、ここで作成されたオブジェクトとはまったく異なるため、現在表示されている Form2 は、ここで参照されているものとは異なります。

誰かが私がやろうとしていることを理解していますか?

4

3 に答える 3

0

Clear関数をForm2パブリックに設定してから、次のようにしてください。

if(frm2.Active == true) frm2.Clear(frm2);

または、フォームのいずれかでこれが必要な場合は、アクティブなフォームをクリアして、Clear関数をForm1に移動し、次のようにします。

if(this.ActiveMDIChild != null)
   Clear(this.ActiveMDIChild);
于 2013-03-05T17:31:36.297 に答える
0

子フォームを作成するときは、子フォームを追跡する必要があります。あなたはこのようなことをしたいかもしれません:

// In the MDI form    
List<Form> mChildForms = new List<Form>();

void ToolStripButton_Click(object sender, EventArgs args)
{
   Form myForm = new FrmUserManager();
   ...
   mChildForms.Add(myForm);
}

void BtnClear_Click(object sender, EventArgs args)
{
   foreach (Form f in mChildForms)
      if (f.Active)
         Clear(f);
}

正確ではないかもしれませんが、私は現在 Visual Studio を持っていません。

于 2013-03-05T17:27:42.497 に答える
0

これらは、この問題を解決するために私が行った手順です。

1. Form を継承し、public ClearData() メソッドを持つクラスを作成します。

public class ClearableForm : Form
{
    public void ClearData()
    {
        Action<Control> traverseControls = null;

        traverseControls = (c) =>
        {
            if (c is TextBox) ((TextBox)c).Text = string.Empty;
            if (c is CheckBox) ((CheckBox)c).Checked = false;
            if (c is DataGridView) ((DataGridView)c).DataSource = null;
            c.Controls.Cast<Control>().ToList<Control>().ForEach(traverseControls);
        };

        traverseControls(this);
    }
}

2. ClearableForm から継承するように FrmUserManager を作成します。

public partial class FrmUserManager : ClearableForm
{
    public FrmUserManager()
    {
        InitializeComponent();
    }
}

3. 次のコードを使用して、"Clear" ToolStripMenuItem を FrmPrincipal フォームの MenuStrip に追加します。

private void clearToolStripMenuItem_Click(object sender, EventArgs e)
{
    foreach (Form mdi_child in this.MdiChildren)
    {
        if (mdi_child is ClearableForm)
            mdi_child.ClearData();
    }
}

問題が解決することを願っています。歓声メイト!

于 2013-03-05T18:55:51.743 に答える