如果我在辅助表单上执行某些操作,如何在主窗体上获取一个方法以在主窗体上执行?

时间:2015-05-03 22:55:55

标签: c# forms partial-classes

每当我更改辅助表单中的某个选项时,我都会尝试在主表单上更新我的数据。

可能的解决方案:

int main (int argc, char * argv[]) { // make sure you were given an image if (argc != 2) { printf("usage: file.img"); return -1; } int fd = open(argv[1], O_RDWR); // make sure you can open the image if(fd == -1) { perror("Error> "); return -1; } struct superblock *mySB; mySB = malloc(sizeof(struct superblock)); read(fd, &mySB, sizeof(struct superblock)); printf("Size: %u, nblocks: %u, ninodes: %u\n", mySB->size, mySB->nblocks, mySB->ninodes); } (主窗体)上公开方法,如下所示:

Form1

然后在次要表单上调用它:

public void updatedata()
{
//data update
}

这不起作用,我相信这是因为他正在尝试更新Form2

我正在使用部分课程,但我对它们并不十分熟悉。

Form1.updatedata()

第二个:

public partial class Form1 : Form
{
  public Form1()
  {
  InitializeComponent();
  }
}

3 个答案:

答案 0 :(得分:1)

我觉得肯定有一个重复的问题来匹配这个。但我一直无法找到它。

根据您发布的代码,如果您使用Opener.updatedata()代替Form1.updatedata(),您的尝试可能会有效。但这仍然不是最佳解决方案。

评论员John Saunders是正确的,正确的方法是在event中声明formOpConfig,然后让Form1订阅它。看起来更像是这样:

public partial class formOpConfig : Form
{
    public event EventHandler UpdateData;

    private void SomethingHappens()
    {
        // do stuff...
        OnUpdateData();
        // maybe do other stuff too...
    }

    private void OnUpdateData()
    {
        EventHandler handler = UpdateData;

        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

上面声明了event,并在适当的时间(即SomethingHappens()时)引发该事件(调用处理程序)。

public partial class Form1 : Form
{
    private void OpenConfigForm()
    {
        OpenConfigForm opConfig = new formOpConfig();

        opConfig.UpdateData += (sender, e) => updatedata();
    }

    // Note that this method is private...no one else should need to call it
    private void updatedata()
    {
        //data update
    }
}

这里,Form1在创建formOpConfig实例时订阅该事件(我假设Form1是创建该实例的内容),并且当调用其处理程序时,它调用您已编写的updatedata()方法。

通过这种方式,这两个类仍然是分离的;即他们实际上并不相互依赖,超出了他们的需要(特别是,formOpConfig班并不需要了解Form1)。

答案 1 :(得分:1)

执行此操作的好方法是使用Event

这允许您解耦表单,因为它们甚至不需要相互引用;基本上,一个事件是你的第二种形式告诉谁可能正在倾听(无需确切知道是谁)发生了感兴趣的事情,并向他们提供有关他们可以使用的有趣事件的一些信息。

  

链接的文章将为您提供比下面更多的细节,这只是一个如何做的快速的想法;我建议您完成本教程!

发生这种情况的机制是,任何想要了解Form2上有趣事件的人都必须订阅Form2上的相应事件;然后每当Form2想要告诉其听众发生了某些事情时,它就会调用已附加到事件的任何事件处理程序。

  

因为事件可以有多个处理程序,所以它是保持应用程序中的组件分离的非常好的方法。

快速演示

(注意:下面的代码不在头顶,所以没有经过测试,没有错误处理等)

首先,您需要声明一个可用于将有趣数据发送给听众的类。该类必须继承自System.EventArgs

public class InterestingEventArgs:EventArgs
{
   public string AnInterestingFact {get;private set;}
   public InterestingEventArgs(string fact)
   {
     AnInterestingFact =fact;
   }
}

只要Form1Form2都可以看到,您在哪里宣布这一点并不重要。

接下来,您必须在Form2上声明一个事件,它必须是公开的,应该如下所示:

public event EventHandler<InterestingEventArgs> SomethingInterestingHappened;

现在您需要决定何时告诉感兴趣的人这个事件。假设您在Form2上有一个按钮,并且您希望在单击它时引发该事件。因此,在按钮的Click处理程序中,您可能具有以下代码:

public void btnRaiseEvent_Clicked(object sender, EventArgs e)
{
   var fact= txtFact.Text;
   var handler = SomethingInterestingHappened;
   if (handler!=null)
   {
      handler(this,new InterestingEventArgs(fact));
   }
}

最后是启动Form2时代码在Form1中的外观,让我们点击Form1上的按钮启动Form2

public void btnShowForm2_Clicked(object sender, EventArgs e)
{
   var child = new Form2();
   child.SomethingInterestingHappened+=OnSomethingInterestingHappened;
   child.Show();
}

最后,您需要在Form1上编写一个事件处理程序,该事件处理程序将在引发事件时被调用:

void OnSomethingInterestingHappened(object sender, InterestingEventArgs e)
{
   MessageBox.Show("Did you know? " + e.AnInterestingFact);
}

答案 2 :(得分:0)

看起来你已经在构造函数中传入了对Form1对象的引用。使用它:

public partial class formOpConfig : Form
{
    private Form1 Opener { get; set; }

    public formOpConfig(Form1 opener)
    { 
        Opener = opener;
    }

    private void updateForm1()
    {
        Opener.updatedata();
    }
}

Form1是一个类,而不是一个对象。如果你使updatedata()成为Form1类的静态方法,你可以说Form1.updatedata(),但这可能与你的其余代码不兼容。