每当我更改辅助表单中的某个选项时,我都会尝试在主表单上更新我的数据。
可能的解决方案:
在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();
}
}
答案 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;
}
}
只要Form1
和Form2
都可以看到,您在哪里宣布这一点并不重要。
接下来,您必须在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(),但这可能与你的其余代码不兼容。