2016-09-26 87 views
-1

有谁知道我在做什么错为什么委托没有在我的代码中工作? 我有一个控制台应用程序,它在开始时显示一个表单,并使用委托更新表单中的标签。.Net委托不工作

namespace DELEGATESAMPLEPROJECT 
{ 
    public class Program 
{ 
    public delegate void OnConfirmCall(); 
    public OnConfirmCall confirmCall; 

    [STAThread] 
    static void Main(string[] args) 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1(new Program().getReference())); 

     new Program().startFunctionCall(); 
    } 

    public Program getReference(){ 
     return this; 
    } 

    public void startFunctionCall(){ 
     Console.WriteLine("Function Call Started!"); 
     if(confirmCall != null){ 
      Console.WriteLine("Function Call Executing..."); 
      confirmCall(); 
     } 
    } 
} 
} 

FORM1

namespace DELEGATESAMPLEPROJECT 
{ 
    public partial class Form1 : Form 
    { 
     public Form1(Program thisProgramClass) 
     { 
      InitializeComponent(); 
      thisProgramClass.confirmCall += saySomething; 
     } 

     public void saySomething() 
     { 
      Label1.Text = "Hello World!"; 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      Label1.Text = "Hi C#!"; 
     } 
    } 
} 

,你可以看到,我试图改变"Hi C#!""Hello World!"但其没有工作,我很想念?

+6

因为您使用了两个完全不同的'Program'实例。这里'Application.Run(new Form1(new Program()。getReference())); '和'new Program()。startFunctionCall();'这里。 –

+0

@ChristophKn请将其作为回答发布 – slawekwin

+0

@ ChristophKn - 我应该重命名程序类吗? – bernzkie

回答

2

那么,你正在使用你的Program类的两个实例。我明白你想要做什么,但是实例化两种形式使他们彼此愚蠢。 Thsy彼此不认识,因此您的confirmCall委托将为空。

解决这个问题很简单。

由于OP想要将实例分配给全局字段。我们宣布它是这样的。另外请注意,我们已经删除了方法,在我们的Program这不应该需要。

private static Program programInstance = new Program(); 

通过这样做,你会得到你Program类的一个实例,它可以在你的窗体类通过传递给你的Form1使用。

Form1 form = new Form1(programInstance); 
Application.Run(form); 

这样,你只有一个实例。但是IMO可以在这种情况下使用SingleTon模式,如果您确实需要一个实例。

作为单身人士的参考,我建议研究关于Singleton pattern的Jon Skeet博客。

+0

我得到了这个错误:'对于非静态字段,方法或属性'Program.programInstance'' – bernzkie

+0

@bernzkie需要一个对象引用,你正在用'Program.programInstance'来做什么。您应该在您的'Program'类中的'Main'方法内插入代码片段。 –

+0

我想声明'programInstance'为全局,所以我可以稍后使用。 : -/ – bernzkie

3
namespace DELEGATESAMPLEPROJECT 
{ 
    public class Program 
    { 
    public delegate void OnConfirmCall(); 
    public OnConfirmCall confirmCall; 

    [STAThread] 
    static void Main(string[] args) 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     var programRef = new Program().getReference(); // <- only one reference. 

     Application.Run(new Form1(programRef)); //Start the form1 

     programRef.startFunctionCall();//Call this function to change the Label in Form1 
    } 

    public Program getReference(){ 
     return this; 
    } 

    public void startFunctionCall(){ 
     Console.WriteLine("Function Call Started!"); //Write this to confirm the function is called 
     if(confirmCall != null){ 
      Console.WriteLine("Function Call Executing...");//Write this to confirm that the delegate is working 
      confirmCall(); 
     } 
    } 
} 
+0

'getReference'方法根本不需要,是吗? – slawekwin

+0

这确实没有要求。但我希望它尽可能与您自己的代码相匹配以防止混淆。 – Blaatz0r