WPF: 使用CommandManager.InvalidateRequerySuggested手動更新Command狀態

https://www.cnblogs.com/zjoch/p/3647236.html

WPF: 使用CommandManager.InvalidateRequerySuggested手動更新Command狀態

WPF判斷命令(Command)是否能夠執行是通過ICommand.CanExecute事件,在實際程序中路由命令一般是通過CommandBinding來使命令得到實際操作代碼,但是這個CanExecute事件的調用是由WPF控制的,有些時候,比如命令執行後進行一些異步耗時操作,操作完成後會影響CanExecute事件結果,但是WPF不會立即做出反應,那麼這個時侯就需要手動調用CommandManager.InvalidateRequerySuggested對命令系統進行一次刷新。

 

比如下面這個小程序

<Window.CommandBindings>
<CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<StackPanel>
<Button Command="New">執行工作</Button>
<TextBlock Name="tbl" Text="等待執行"></TextBlock>
</StackPanel>

 

事件執行:

//
// 事件執行代碼
//

privatevoid CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute =!finished;
}

privatevoid CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
    System.Threading.ThreadPool.QueueUserWorkItem(dowork);
}

bool finished =false;
void dowork(object obj)
{
    updateUI("開始工作");
    System.Threading.Thread.Sleep(1000);
    updateUI("工作結束");
    finished =true;
}

void updateUI(string msg)
{
    Dispatcher.BeginInvoke((Action)(() => tbl.Text = msg));
}

程序按鈕點擊後下面文字顯示“工作結束”,這時按鈕理應是禁用的(因爲此時CanExecute結果是false),但實際上按鈕沒有被禁用,只有界面發生改變後(如焦點,按鍵變化,或者按鈕再次被點擊),按鈕纔會被禁用,因爲此時WPF才調用相應的CanExecute事件。

 

手動調用CommandManager.InvalidateRequerySuggested就可以解決問題,注意這個函數只有在UI主線程下調用纔會起作用。 

void dowork(object obj)
{
    updateUI("開始工作");
    System.Threading.Thread.Sleep(1000);
    updateUI("工作結束");
    finished =true;
//手動更新
    updateCommand();
}

void updateCommand()
{
    Dispatcher.BeginInvoke((Action)(() =>CommandManager.InvalidateRequerySuggested()));
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章