亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

GUI 在單擊之前不響應

GUI 在單擊之前不響應

C#
九州編程 2022-01-09 15:09:25
我有一個與這里類似的問題:WPF MVVM Light: Command.RaiseCanExecuteChanged() doesn't work,使用帶有 WPF 的命令并且我的 GUI 無法工作,直到我單擊屏幕中的某個位置。我不使用 MVVM Light。我通過調用 ExternalDLL.Start() 調用外部 DLL 來執行某些操作,然后調用 GetStatus() 以了解操作是否已開始。如果我得到正確的狀態作為回報,我改變了實際的行動,它必須激活我的 GUI 上的一個按鈕。在我單擊某個地方之前,該按鈕不會自行激活。我檢查了線程,但它似乎在同一個線程上,我試圖將它放在 GUI 線程中,通過使用Application.Current.Dispatcher.BeginInvoke,但它也不起作用。這是我的代碼:private async void StartScanCommand_Executed(object sender, ExecutedRoutedEventArgs e){      ExternalDLL.Start();      WaitForStarting();}private async void WaitForStarting(){    Waiting();    Stopwatch chrono = new Stopwatch();    chrono.Start();    bool started = false;    while (chrono.ElapsedMilliseconds < 20000)    {        if (ExternalDLL.GetStatus() != ExternalDLL.Status.Started)        {            await Task.Delay(100);        }        else        {            started = true;            chrono.Stop();            StartedAction();            break;        }    }    if (!started)    {        MessageBox.Show("Error");    }}該Waiting()方法調用激活GUI和工作的按鈕。但是StartedAction()也必須激活一個按鈕,并且不起作用。這是開始操作的代碼:private void StartedAction(){    _actualAction = ActualAction.DoingAction;}這是按鈕的可以執行方法:private void SomeButtonCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) {     e.CanExecute = _actualAction == ActualAction.DoingAction; }我究竟做錯了什么 ?
查看完整描述

2 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

問題很簡單,當ActualAction值更改時,綁定命令的 CanExecute 狀態不會重新評估。


要求CommandManager.InvalidateRequerySuggested()強制重新評估。


private void StartedAction()

{

    _actualAction = ActualAction.DoingAction;

    CommandManager.InvalidateRequerySuggested();

}


查看完整回答
反對 回復 2022-01-09
?
瀟瀟雨雨

TA貢獻1833條經驗 獲得超4個贊

您正在 UI 線程上進行后臺工作。不要在那里做,在另一個線程中做,并使用輪詢、事件或其他回調方法來更新 UI(在 UI 線程上)。


例如,您可以這樣做:


Task.Run(() => { OtherDll.DoWork(); };

這將啟動外螺紋上的其他工作。


如果您需要更多控制,您可以將其他 dll 的功能單獨包裝在一個線程中。


Public Class OtherDLLThread 

{

    Thread _internalThread;


    public OtherDLLThread()

    {

         _internalThread = new Thread(ThreadMainLoop);

    }


    public void ThreadMainLoop()

    {

        OtherDLL.DoWork();

    }


    public static void Start() 

    {

       _internalThread.Start();

    }


}

像這樣使用它:


OtherDLLThread other = new OtherDLLThread();

other.Start();

這是另一個將代碼插入 UI 線程的函數:


    /// <summary>

    ///     Runs the action on UI thread.

    /// </summary>

    /// <param name="action">The action.</param>

    public static void RunOnUIThread(Action action)

    {

        try

        {

            if (Application.Current != null)

                Application.Current.Dispatcher.Invoke(action);

        }

        catch (Exception ee)

        {

            _logger.Fatal("UI Thread Code Crashed. Action detail: " + action.Method, ee);

            //SystemManager.Instance.SendErrorEmailToCsaTeam("Kiosk Application Crashed", "UI Thread Code Crashed. Action detail: " + action.Method);

            throw;

        }

    }

像這樣使用它:


RunOnUITHread(() => lblStatus.Text = "Working...");


查看完整回答
反對 回復 2022-01-09
  • 2 回答
  • 0 關注
  • 288 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號