1

メイン フォームには 1 つのボタンがあります。ボタンがクリックされると、グリッドにデータが入力されます。これが私のボタンクリックルーチンです

private void btnSearch_Click(object sender, EventArgs e)
{
    if (chkExcludeCallCust.Checked)
    {
        if (chkEnable.Checked)
            RangeExclude = 1;
        else
            RangeExclude = 0;
    }

    new Thread(() =>
    {
        lock (thisLock)
        {
            Search();
        }
    }).Start();

}

ユーザーが検索ボタンをクリックすると、スレッドが呼び出されます。そのスレッドから、データベースからデータを取得し、グリッドに入力します。

だからここに私の検索ルーチンがあります:

private void Search()
{
    DataSet ds = null;

    if (wfrm.InvokeRequired)
    {
        wfrm.Invoke(new MethodInvoker(delegate
        {
            wfrm.Show();
            wfrm.Refresh();
            Application.DoEvents();
        }));
    }
    else
    {
        wfrm.Show();
        wfrm.Refresh();
        Application.DoEvents();
    }

    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(delegate { 
            this.Cursor = Cursors.WaitCursor;
            btnSearch.Enabled = false;
        }));
    }
    else
    {
        this.Cursor = Cursors.WaitCursor;
        btnSearch.Enabled = false;
    }

    if (!PingTest())
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new MethodInvoker(delegate
            {
                this.Cursor = Cursors.Default;
                MessageBox.Show("VPN disconnected. Please connect and try again.", "DebtorCallerAssistance");
                return;
            }));
        }
        else
        {
            this.Cursor = Cursors.Default;
            MessageBox.Show("VPN disconnected. Please connect and try again.", "DebtorCallerAssistance");
            return;
        }
    }

    if (chkExcludeCallCust.InvokeRequired)
    {
        chkExcludeCallCust.Invoke(new MethodInvoker(delegate
        {
            DataLayer.SetConnectionString(_country);
            ds = LoadData(dtfrom.Value.ToString("yyyyMMdd"), dtto.Value.ToString("yyyyMMdd"), (chkExcludeCallCust.Checked ? 1 : 0), txtSearch.Text, 1, Pager.PageSize, false);
        }));
    }
    else
    {
        DataLayer.SetConnectionString(_country);
        ds = LoadData(dtfrom.Value.ToString("yyyyMMdd"), dtto.Value.ToString("yyyyMMdd"), (chkExcludeCallCust.Checked ? 1 : 0), txtSearch.Text, 1, Pager.PageSize, false);
    }

    if (ds.Tables.Count > 0)
    {
        if (ds.Tables[0] != null)
        {
            dtExport = ds.Tables[0];
        }
    }

    if (outlookGrid1.InvokeRequired)
    {
        outlookGrid1.Invoke(new MethodInvoker(delegate
        {
            outlookGrid1.BindData(ds, "data");
            View = "BoundInvoices";
            DataGridViewCellEventArgs evt = new DataGridViewCellEventArgs(2, -1);
            object sender = null;
            //outlookGrid1_CellClick(sender, evt);
        }));
    }
    else
    {
        //outlookGrid1.DataSource = ds.Tables[0];
        outlookGrid1.BindData(ds, "data");
        View = "BoundInvoices";
        DataGridViewCellEventArgs evt = new DataGridViewCellEventArgs(2, -1);
        object sender = null;
        //outlookGrid1_CellClick(sender, evt);
    }

    if (wfrm.InvokeRequired)
    {
        wfrm.Invoke(new MethodInvoker(delegate
        {
            wfrm.Hide();
        }));
    }
    else
    {
        wfrm.Hide();
    }

    if (this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(delegate { 
        this.Cursor = Cursors.Default;
        btnSearch.Enabled = true;
        }));
    }
    else
    {
        btnSearch.Enabled = true;
        this.Cursor = Cursors.Default;
    }
}

フォームの読み込み時に、次のようなボーダーレス ウィンドウをインスタンス化します。

WaitForm wfrm = null;
public Feedback(string country)
{
    InitializeComponent();
    wfrm = new WaitForm();
}

また、このウィンドウに次のようないくつかのプロパティを設定します。

startposition = CenterScreen
showinicon=false
showintaskbar=false
formboderstyle=none

WaitForm検索ボタンを 1 回クリックしたときにのみ表示される 検索ボタンを 2 回目にクリックしたときに が表示されない理由がわかりWaitFormません。

もう 1 つの問題は、アニメーション GIF が割り当てられている がPictureBoxある ことです。アニメーションが再生されていないことがWaitForm初めて表示されます。WaitFormWinForm を表示したときにアニメーションが再生されないのはなぜですか?

WaitForm検索ボタンをクリックするたびに を表示するには、コードで何を変更する必要があるか教えてください。GIFをアニメートWaitFormする方法も知りたいです。PictureBox

4

1 に答える 1

1

スレッドを開始して、すべてを GUI スレッドに戻すのはまったくナンセンスです。そして、DoEvents はコードの匂いの指標です。呼び出しが大きなオーバーヘッドを作成するので、呼び出しをバンドルします

コードを次のように変更します。

   private void btnSearch_Click(object sender, EventArgs e)
    {
        this.btnSearch.Enabled = false;
        this.Cursor = Cursors.WaitCursor;
        this.wfrm.Show();

        Thread t = new Thread(this.Search);
        t.Start();
    }

    private void Search()
    {
        while (isWorking)
        {
            DoHeavyWork();
            this.Invoke(new Action(ReportToWaitForm);
        }

        this.Invoke(new Action(() =>
            {
                this.btnSearch.Enabled = true;
                this.Cursor = Cursors.Default;
                this.wfrm.Hide();
            }));
    }
于 2013-07-30T10:28:34.567 に答える