サーバーからクライアントにファイルを転送するソフトウェアを作成しようとしています...これが私のソフトウェアの動作です。クライアント側では、IPを取得し、ポートがClientクラスから新しいオブジェクトを生成します。新しいスレッドに移動し、ipとポートをコンストラクターに渡し、クライアントが接続を処理してファイルをbyte []変数に転送します。ここで、saveFileDialogを使用してユーザーにファイルを保存するように求めます...しかしフォームである親クラスにアクセスできません。だから私はsavefiledialog.ShowDialog()のようなことをすることができません...この問題の解決策は何ですか?
2 に答える
イベントを使用する
http://msdn.microsoft.com/en-us/library/awbftdfh.aspx
独自のスレッドの代わりにバックグラウンドワーカーを使用します。
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.100).aspx
@synedが提案したイベントは良い解決策です。これは一種のオブザーバーですが、この例では、オブザーバブルクラス(クライアント)と対話する必要があります。
クライアントクラスでイベントを宣言できるため、ファイルを受信するときにこのイベントを使用できます。通常のアプローチは、必要な値を入力する特別な「コンテキストクラス」を用意することです。
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
ます。
+=
構文にも注意してください。関数にイベントを割り当てるのではなく、何かが起こったときに関数を呼び出すようにイベントに指示します。必要に応じて、同じイベントに2つの関数を含めることもできます。