-2

我有一个连接到服务器的简单登录表单。

当用户按下登录按钮时,动画加载 GIF 需要显示,直到建立连接或连接失败。

理论上,我做到了:

private void button_login_Click(object sender, EventArgs e)
{
        button_login.Text = WORKING;
        Loading(ShowMode.show, pictureBox_login_loading);
        // send request         
        client = new TcpClient();
        try
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
            client.Connect(endPoint);
            // send login details .. :)
            output = client.GetStream();
            writer = new BinaryWriter(output);
            reader = new BinaryReader(output);
            // write details
            writer.Write("login"   "|"   userID   "|"   privateName);
        }
        catch (Exception)
        {
            MessageBox.Show("Server is down.");
            return;

        }
        finally
        {
            // Stop loading and return status
            button_login.Text = DEFAULT_LOGIN_TEXT;
            Loading(ShowMode.hide, pictureBox_login_loading);
        } 
}

Loading 是一个将 PictureBox 的 Visible 属性设置为 的函数Visible。(我认为这会有所帮助)

问题是:gif 仅在button_login_Click完成运行后才可见,并且在它不可见之后才可见。

如何使动画 gif 在它正在执行的行上可见?

4

2 回答 2

3

问题是您没有退回到 GUI 线程,因此无法显示您的 GIF。

我建议使用 BackgroundWorker 连接到您的客户端,然后在开始工作之前显示 GIF 并在 Worker 完成的调用中停止它。

示例代码(注意,我没有编译它,因为我没有足够的源代码来编译):

       button_login.Text = WORKING;
        Loading(ShowMode.show, pictureBox_login_loading);
        // send request      
        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += new DoWorkEventHandler((obj, args) =>
        {
            client = new TcpClient();
            try
            {
                IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
                client.Connect(endPoint);
                // send login details .. :)
                output = client.GetStream();
                writer = new BinaryWriter(output);
                reader = new BinaryReader(output);
                // write details
                writer.Write("login"   "|"   userID   "|"   privateName);
            }
            catch (Exception)
            {
                this.Invoke(new Action(() =>MessageBox.Show("Server is down."));
            }
        });

        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) =>
        {
            button_login.Text = DEFAULT_LOGIN_TEXT;
            Loading(ShowMode.hide, pictureBox_login,loading);
        });

        worker.RunWorkerAsync();

这种方法让 GUI 线程允许它显示您的 GIF 并仍然监视您的连接并删除 GIF 并在完成后恢复按钮文本。

于 2013-02-13T19:01:48.877 回答
0

由于它是您所追求的动画,因此您可能需要在另一个线程上启动连接,以免 UI 线程被阻塞。如果是静止图像,你可以调用图片框的Update()方法让它显示出来。但对于你的情况,这样的事情应该有效:

Thread thread = new Thread(new ThreadStart(delegate
{
    Invoke((Action)(()=>{ button_login.Text = WORKING; Loading(ShowMode.show, pictureBox_login_loading); }));
    // send request         
    client = new TcpClient();
    try
    {
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5000);
        client.Connect(endPoint);
        // send login details .. :)
        output = client.GetStream();
        writer = new BinaryWriter(output);
        reader = new BinaryReader(output);
        // write details
        writer.Write("login"   "|"   userID   "|"   privateName);
     }
     catch (Exception)
     {
         MessageBox.Show("Server is down.");
         return;

     }
     finally
     {
         // Stop loading and return status
         Invoke((Action)(()=>{ button_login.Text = DEFAULT_LOGIN_TEXT; Loading(ShowMode.hide, pictureBox_login_loading); }));
      } 
}));
thread.Start();

您也可以像讨论的其他答案一样使用 BackgroundWorker,但我倾向于将它们保留用于运行时间更长的任务,例如使用进度条报告进度的任务。如果它是一个简短的(ish)任务,我通常在 .NET 4.0 中使用Thread, 或。Task.Factory.StartNew

于 2013-02-13T19:03:13.257 回答