2017-01-14 5 views
1

私はC#で書かれた100のウィンドウフォームを持っていると仮定して、これらのフォームのいずれかのコードを変更することなく、また他のフォームから継承せずにこれらのフォームのロード時に呼び出される関数を定義する方法があります。それは新しいフォームが開いているときに自動的に呼び出される関数ですか?C#ですべてのフォームロードで関数を呼び出す方法は?

ありがとう、

+0

どのようにあなたのフォームをインスタンス化していますか?あなたはデコレータを使うことができます。 –

+0

私はこの質問がなぜ下降されているのか分かりません。それは完全に有効な質問です。 – CodingYoshi

答えて

1

このような方法はありません。あなたはあなたの質問で言った解決策の1つを使用するだけです。

2

MessageFilterを使用して、フォームの読み込みに関するメッセージを傍受することができます。以下は、フォームをインターセプトし、イベントハンドラをイベントに追加するサンプルです。あなたはイベントハンドラで必要なことをすることができます。

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     Application.AddMessageFilter(new TestMessageFilter()); 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

} 

私はあなただけのloadイベントの前にはなく、以下のコードでは発生しませんLoadイベントに加入何らかの理由でコードを実行する必要があります知っています。しかし、あなたがActivatedイベントでそれを行うことができれば、それはうまくいくでしょう。あるいは、別のイベントでそれをやりたければ、以下のコードを修正して、そのイベントがトリガーされるかどうかを確認してください。同じフォームの同じイベントに対して複数のハンドラを追加しないように、コードはすべてのフォームのリストも保持しています。フォームが閉じられると、すべてのハンドラが削除されます。

[SecurityPermission(SecurityAction.LinkDemand, Flags = 
SecurityPermissionFlag.UnmanagedCode)] 
public class TestMessageFilter : IMessageFilter 
{ 
    private Hashtable forms = new Hashtable(); 
    public bool PreFilterMessage(ref Message m) 
    { 
     Control c = Control.FromHandle(m.HWnd); 

     var form = c as Form; 
     if (form != null && 
      !this.forms.ContainsKey(form)) 
     { 
      form.Load += Form_Load; 
      form.Activated += Form_Activated; 
      form.FormClosed += Form_FormClosed; 
      this.forms.Add(form, form); 
     } 

     return false; 
    } 

    private void Form_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     if (this.forms.ContainsValue(sender)) 
     { 
      var f = sender as Form; 
      f.Activated -= Form_Activated; 
      f.Load -= Form_Load; 
      this.forms.Remove(sender); 
     } 
    } 

    private void Form_Activated(object sender, EventArgs e) 
    { 
     MessageBox.Show("Form_Activated..."); 
    } 

    private void Form_Load(object sender, EventArgs e) 
    { 
     MessageBox.Show("Form_Load..."); 
    } 
} 
0

フォームファクトリを使用して、OnLoadメソッドまたはフォームクラス内の他の仮想メソッドをインターセプトするインターセプトを実装できます。

Autofac、Castle.Core、およびAutofac.Extras.DynamicProxyを使用して、各フォームのOnLoadメソッドをインターセプトし、フォームにOnLoadメソッドが呼び出される前と後にコンソールに書き込むという概念証明を作成しました。

フォームファクトリバックオーナーズ。 CreateForm(string formName)は、名前付きAutofacサービスの名前をとります。

public interface IFormFactory 
{ 
    Owned<Form> CreateForm(string formName); 
} 
public class FormFactory : IFormFactory 
{ 
    private readonly IContainer _container; 
    public FormFactory(IContainer container) 
    { 
     _container = container; 
    } 
    public Owned<Form> CreateForm(string formName) 
    { 
     return _container.ResolveNamed<Owned<Form>>(formName); 
    } 
} 

以下のインターセプタは、フォーム上の仮想メソッドごとに呼び出されます。 OnLoadのチェックを追加しましたが、他の仮想メソッドも傍受して呼び出すことができます。

public class FormInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) 
    { 
     bool isFormOnLoad = invocation.InvocationTarget is Form && invocation.Method.Name.Equals("OnLoad"); 

     if(isFormOnLoad) 
     { 
      Console.WriteLine("Before OnLoad"); 
     } 
     invocation.Proceed(); 
     if(isFormOnLoad) 
     { 
      Console.WriteLine("After OnLoad"); 
     } 
    } 
} 

インターセプタ、フォーム、および工場で名前付きサービスを使用するように登録してください。名前は、ファクトリメソッドでフォームを作成するために使用されます。以下は

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterType<FormInterceptor>(); 

     Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add<System.Security.Permissions.UIPermissionAttribute>(); 

     // Register your forms 
     builder.RegisterType<frmMain>() 
      .Named<Form>("frmMain") 
      .EnableClassInterceptors() 
      .InterceptedBy(typeof(FormInterceptor)); 

     builder.RegisterType<frmSubForm>() 
      .Named<Form>("frmSubForm") 
      .EnableClassInterceptors() 
      .InterceptedBy(typeof(FormInterceptor)); 


     FormFactory = new FormFactory(builder.Build()); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(FormFactory.CreateForm("frmMain").Value); 
    } 

    public static IFormFactory FormFactory { get; set; } 
} 

メインフォーム内の試験フォームを作成し、表示の一例です:

private void button1_Click(object sender, EventArgs e) 
    { 
     using (var subForm = Program.FormFactory.CreateForm("frmSubForm").Value) 
     { 
      subForm.ShowDialog(this); 
     } 
    } 
関連する問題