我正在尝试编写一个将文件从服务器传输到客户端的软件......这就是我的软件的工作方式..在客户端,它获取了一个IP和一个端口然后从中生成一个新对象Client类到一个新的Thread并将ip和port传递给构造函数,客户端处理连接并将文件传输到byte []变量。现在我想用saveFileDialog提示用户保存文件。 ..但我无权访问作为我的表格的父类。所以我不能做像savefiledialog.ShowDialog()这样的问题...这个问题的解决方案是什么?
答案 0 :(得分:2)
使用活动
http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
使用后台工作程序而不是您自己的主题:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx
答案 1 :(得分:2)
@syned建议的事件是一个很好的解决方案。它有点observer,但在本例中,您需要与可观察类(客户端)进行交互。
您可以在客户端类中声明一个事件,因此当要接收文件时,可以使用此事件。一种常见的方法是使用一个特殊的“上下文类”,用你需要的值填充它。
public class Client {
public event EventHandler<ReceivedFileEventArgs> ReceivedFile;
private ReceivedFileEventArgs onReceivedFile() {
EventHandler<ReceivedFileEventArgs> handler = ReceivedFile;
ReceivedFileEventArgs args = new ReceivedFileEventArgs();
if (handler != null) { handler(this, args); }
return args;
}
private void receiveFileCode() {
// this is where you download the file
ReceivedFileEventArgs args = onReceivedFile();
if (args.Cancel) { return; }
string filename = args.FileName;
// write to filename
}
}
public class ReceivedFileEventArgs {
public string FileName { get; set; }
public bool Cancel { get; set; }
}
现在,在您的GUI类中,您可以“监听”此事件,并将文件名设置为您想要的内容。
public class MyForm : Form {
public MyForm() { Initialize(); }
protected void buttonClick(object sender, EventArgs e) {
// Suppose we initialize a client on a click of a button
Client client = new Client();
// note: don't use () on the function here
client.ReceivedFile += onReceivedFile;
client.Connect();
}
private void onReceivedFile(object sender, ReceivedFileEventArgs args) {
if (InvokeRequired) {
// we need to make sure we are on the GUI thread
Invoke(new Action<object, args>(onReceivedFile), sender, args);
return;
}
// we are in the GUI thread, so we can show the SaveFileDialog
using (SaveFileDialog dialog = new SaveFileDialog()) {
args.FileName = dialog.FileName;
}
}
}
那么,什么是活动?在简单术语中,它是一个函数指针(但请阅读它以获取更多详细信息)。因此,当发生某些事情时,例如,当要接收文件时,您告诉客户端类调用该函数。您在使用Windows窗体时几乎总是使用事件,例如当您在代码隐藏文件中为某个函数指定按钮时。
现在,使用此模式,您可以拥有更多事件,例如FileDownloadCompleted
。
另请注意+=
语法。您没有将事件分配给某个函数,您告诉事件在发生某事时调用该函数。如果需要,您甚至可以在同一事件上拥有两个函数。