正在实现一个局域网的文件传输,要求是在主窗口中双击一个联系人后,弹出发送文件的窗口,选择要发送的文件后按确定发送。接收端收到文件传输请求后,弹出接收窗口,确认接收后双方建立连接,开始传文件。
我把所有的控制都写在一个控制类里,比如监听,数据包检查,发送线程和接收线程等。现在的问题是我在主窗体的图标双击事件里生成的发送窗体,用的是showdialog方法,我希望通过对窗体的操作后在主窗体里做发送文件请求。(主窗体里申明的控制类)。可是showdialog方法必须要等窗体关闭后才能执行之后的语句。可是我又想在发送窗体里实现进度条的显示。接收方也存在同样的问题,请问应该如何处理?

解决方案 »

  1.   

    不要showdialog,甚至不用show任何的窗口(用户还得把它关掉对不对?)。你的程序还更简单。
      

  2.   

    主窗体
    using System;
    using System.Windows.Forms;namespace WindowsApplication39
    {
        public partial class Form1 : Form
        {        delegate void dShowForm();
            Form2 frm = new Form2();        public Form1()
            {
                this.InitializeComponent();
            }
            //显示窗体
            void ShowForm()
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new dShowForm(this.ShowForm));
                }
                else
                {
                    frm.ShowDialog(this);
                }
            }
            //控制进度
            void SetProgress()
            {
                for (int i = 1; i <= 100; i++)
                {
                    if (frm.DialogResult == DialogResult.Cancel)
                    {
                        //判断取消
                        break;
                    }
                    else
                    {
                        //模拟进度
                        frm.SetProgress(100, i);
                        System.Threading.Thread.Sleep(50);
                    }
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                new System.Threading.Thread(new System.Threading.ThreadStart(ShowForm)).Start();
                new System.Threading.Thread(new System.Threading.ThreadStart(SetProgress)).Start();
            }
        }
    }模态子窗体
    using System;
    using System.Windows.Forms;
    namespace WindowsApplication39
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }        public delegate void dSetProgress(int total, int current);        public void SetProgress(int total, int current)
            {
                if (this.InvokeRequired)
                {
                    try
                    {
                        this.Invoke(new dSetProgress(this.SetProgress), new object[] { total, current });
                    }
                    catch { }
                }
                else
                {
                    this.progressBar1.Maximum = total;
                    this.progressBar1.Value = current;
                }
            }        private void button1_Click(object sender, EventArgs e)
            {
                this.DialogResult = DialogResult.Cancel;
            }
        }
    }
      

  3.   

    有jinjazz ,我看我又捞不到分拉.
      

  4.   

    具体怎么写 我就不写了 我提供一个参考思路 你可以把[发送文件请求]做在后面showDialog这个发送窗体from.load里 这样发送窗体起来的时候会弹出这个请求确认
      

  5.   

    谢谢jinjazz和其他回答的朋友!我程序中的协议是这样的:由于发送窗体时主动打开,故其showdialog方法在主窗体的响应事件中。我要根据发送窗体中选择的发送文件的内容再向接收方发送请求传文件的数据包(包括文件名、大小、本机计算机名和IP等),接收方收到消息确认接收后启动监听线程,并发回一个确认数据包,然后发送方再启动控制类中的发送线程。
    如果发送窗体用线程方式启动的话,他就独立出来了,如何根据窗体中选择的内容启动另一个控制类中的发送文件请求方法呢?还有进度条是在双方达成协议确认传输时开始,jinjazz的代码中进度条是不是从打开form2开始就显示了呢?我对委托还不是很熟练,jinjazz代码里的委托不需要赋值吗?比如加上dShowForm ddShowForm = new dShowForm(ShowForm);还是直接像他那样就可以用了呢?
      

  6.   


    我开始就是这样写的,虽然程序可以正常运行,但是发送文件请求在控制类中,那样的话又要申明一个控制类的对象,程序复杂后容易引起调用逻辑上的循环,不是好的设计模式。跟开始的MVC设计模式相违背了吧。所以后来就改成这样了整个过程只用一个控制类对象。
      

  7.   

    关键我下面的步骤要通过发送窗体的操作决定,比如发送窗体中选择好文件后点发送按钮,然后需要将这个消息和一个文件路径的string传到主窗体,如果用户取消的话就什么都不做。如何在线程中将消息返回?现在还不知道怎么把这段代码插入工程中完成所有逻辑,还是测试不了。。还是请教下啊~!!
      

  8.   

    谢谢,你的代码我已经理解了,也加到工程里了,就是进度条部分还是不行。进度条显示要在发送方发送文件发送请求后再接收方弹出接收窗体,经确认后接收方发回一个信息,然后再建立连接开始传文件,那个时候进度条才开始运行。请问有好的解决方案吗?还有我现在的程序运行后点击发送按钮后发送端窗体自动就消失了,代码如下private void btn_send_Click(object sender, EventArgs e)
            {
                tempfname = tb_sendfile.Text;            if (tempfname == "")
                {
                    MessageBox.Show("请选择要发送的文件!");
                    return;
                }
                else if (!File.Exists(tempfname))
                {
                    MessageBox.Show("请输入存在的文件名!");
                    tb_sendfile.Focus();
                    tb_sendfile.SelectAll();
                    return;
                }
                Form1.saveFile = tempfname;            this.DialogResult = DialogResult.Yes;
            }什么原因呢?
      

  9.   

    this.DialogResult = DialogResult.Yes;
    会关闭当前窗体我写的是比较通用的结构,具体怎么套入你的业务逻辑,你自己分析吧。