【问题标题】:WPF Using commands to slow to update UI controlsWPF 使用命令减慢更新 UI 控件的速度
【发布时间】:2011-02-02 05:03:48
【问题描述】:

我通过命令属性将命令绑定到按钮,并在放置它的页面中进行命令绑定。在执行方法中,我创建了一个包含后台工作者的类的实例并启动它(这是一项漫长的任务)。后台工作者 (bw) 类包含一个变量 isRunning,在执行 DoWork 方法之前将其设置为 true,在执行 RunWorkerCompleted 时将其设置为 false。因此,从放置按钮的页面后面的代码中,在 CanExecute 方法中,如果 bw 没有运行(isRunning = false),我将 e.canExecute 设置为 true,如果 isRunning = true,则将 e.canExecute 设置为 false。

当我按下按钮时,它会长时间启动 bw 进程并且按钮被禁用。好的,这是正确的,但是当后台工作人员 (bw) 完成时,该按钮不会返回启用状态,直到我再次按下它。当它被禁用并且我按下(当 bw 完成时)它被启用。为什么按钮在 bw 末尾没有自动返回启用状态?

我的代码 sn-p:

<Page  x:Class="GParts.Pages.MyPage" 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"       
   xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;
    assembly=PresentationFramework.Aero"            
    xmlns:local="clr-namespace:GParts"      
    Loaded="Page_Loaded"  
    Unloaded="Page_Unloaded" 
    Height="Auto">

  <Page.CommandBindings>
    <CommandBinding Command="{x:Static local:Pages.MyPage.rcmd}"
               Executed="CommandBinding_Executed"
               CanExecute="CommandBinding_CanExecute"/>
  </Page.CommandBindings>

   <...>
   <Button Command="{x:Static local:Pages.MyPage.rcmd}" />

<...>
</Page>

页面背后的代码:

 namespace GParts.Pages
 {

   public partial class MyPage : Page
   {

    public static RoutedCommand rcmd = new RoutedCommand();

    private cBgWorker bw;

    <...>

    // ExecutedRoutedEventHandler for the custom button remove all command.
    private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
    {

            // get an isntance of the background worker class
            bw = new cBgWorker();

            // start the long task
            bw.StartTask();

    }

    // CanExecuteRoutedEventHandler for the custom button remove all command.
    private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        // bw is the instance of background worker class
        if (bw == null)
        {
            e.CanExecute = true;
        }
        else
        {
            e.CanExecute = !bw.isRunning;// isRunning indicates if bw is
                                         //executing now         
        }
    }

    <...>

} // end class
} // end namespace

【问题讨论】:

  • 您可能还需要考虑检查(许多)问题并酌情标记一些答案。只需单击对您最有帮助的答案旁边的小“复选标记”......

标签: wpf button command performance


【解决方案1】:

BackgroundWorker 完成后,调用 CommandManager.InvalidateRequerySuggested();

默认情况下,命令只是偶尔被 WPF 请求。否则,在每个ICommand 实现上不断调用“CanExecute”会产生大量开销。调用上述方法会强制 CommandManager 立即更新。

这将强制命令适当地重新启用/禁用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多