关闭此表单打开的表单

时间:2016-03-12 13:37:16

标签: c# multithreading forms

我正在为学校项目编写聊天应用程序。我有一种形式是“联系人”表单,我从中打开了不同的SingleDialogue表单(它们是1对1的聊天记录)。我想这样做,当我关闭Contacts表单时,它会关闭我打开的所有SingleDialogue表单。

为此,我这样做,以便Contacts_FormClosing事件触发客户端对象中的Disconnected事件,并在Contacts表单中创建了一个方法:

private void On_ImDisconnected(object sender, EventArgs e)
{
    foreach (SingleDialogue sd in singleChats)
        sd.Close();
}

singleChats是从“联系人”表单打开的SingleDialogue表单列表的名称。每次我打开另一个SingleDialogue时,都会将其添加到singleChats中。 在构造函数中,我将它订阅到客户端对象中的Disconnected事件:

im.Disconnected += new EventHandler(On_ImDisconnected);

到目前为止,当我在客户端对象On_ImDisconnected中触发Disconnected事件时,会触发并关闭所有SingleDialogues,对吗?

但我得到一个例外,说#34;跨线程操作无效:Control' SingleDialogue'从在"上创建的线程以外的线程访问。

好吧,然后我改变了On_ImDisconnected:

private void On_ImDisconnected(object sender, EventArgs e)
{ 
    this.BeginInvoke(new MethodInvoker(delegate
    {
        foreach (SingleDialogue sd in singleChats)
            sd.Close();
    }));
}

但现在没有任何反应。你能帮助我解决这个问题吗?

编辑:

清单声明:

List<SingleDialogue> singleChats = new List<SingleDialogue>();

添加新成员:

private void chatButton_Click(object sender, EventArgs e)
{
    SingleDialogue sd = new SingleDialogue(im, chatTextBox.Text);
    singleChats.Add(sd);
    chatTextBox.Text = "";
    sd.Show();
}

2 个答案:

答案 0 :(得分:1)

我要说完全跳过列表。在#include <vector> #include <string> #include <iostream> namespace DataWorld { using DataType = int; // It is a data. Holder struct will hold this data. But holder has it's id struct Data { DataType storage[5]; void Show() { std::cout << "my_holder_index" << " "; // here the data has to know the id of the holder that holds this data for(auto elem : storage) { std::cout << elem << " "; } std::cout << std::endl; } }; struct DataHolder { Data my_data; std::string my_holder_index; DataHolder(Data my_data, std::string my_holder_index) : my_data(my_data) , my_holder_index(my_holder_index) {} void Show() { // Do not show holder id here! It is the data that has to know it. my_data.Show(); } }; } int main() { using namespace DataWorld; DataHolder dhs[] = { { {1, 2, 3, 4, 5}, "nat" }, { {1, 3, 5, 7, 9}, "even" }, { {2, 4, 6, 8, 10}, "odd" } }; for(auto dh : dhs) { dh.Show(); } } 表单的构造函数中,您可以在传递的父级断开连接时添加处理程序,然后从其自身内部关闭SingleDialogue

因此,如果我不得不猜测构造函数的样子,你可以这样做:

SingleDialogue

请注意,我不是本地C#开发人员,所以如果我做错了请告诉我。 :)

答案 1 :(得分:0)

据我了解情景,您在联系表单中保留了一个表单列表,并希望将其关闭。

当您将每个表单订阅到Disconnected事件时,我认为您的方法是错误的。为什么不从它内部关闭事件触发器上的表单?

您只需要在每个SingleDialogue实例中使用此代码:

//subscribe to event handler, most probably in constructor
im.Disconnected += new EventHandler(On_ImDisconnected);

//close on event fire
private void On_ImDisconnected(object sender, EventArgs e)
{ 
    this.Close();
}

您无需浏览list并关闭父表单中的表单。

如果我的问题出错了,请纠正我。