WPF中异步更新Command可用逻辑时按钮状态没有更新

  在这样一种场景,通过点击一个按钮来执行一段耗时的逻辑,在这段逻辑执行完时设置另外一个按钮的可用状态,通过CanExecuted影响。示例如下:

  

  其中,扫行逻辑的代码如下:

  

        private ICommand _setWaitCommandExecuted;

        public ICommand SetWaitCommandExecuted
        {
            get
            {
                if (null == _setWaitCommandExecuted)
                    _setWaitCommandExecuted = new RelayCommand(() =>
                    {              //异步线程
                        Task.Run(() =>
                        {
                            System.Threading.Thread.Sleep(1000);//模拟耗时操作
                            CanWaitExecuted = true;//设置Wait的状态可用,对于Wait的Command中的CanExecuted,只是简单的返回该值
                        });
                    });
                return _setWaitCommandExecuted;
            }
        }

  F5运行结果如下:

  UI上Wait的按钮没有刷新。这是一个问题。经过从网上查找资源,发现了一种解决方式。

  方案一:

  既然UI上绑定按钮的状态没有刷新,那就用一种比较霸道的方式,强制让UI刷新按钮的状态,即调用CommandManager.InvalidateRequerySuggested()这段代码。注意这句代码需要封送到UI线程中执行。

  方案二:

  出现该问题的一个原因在于异步线程中列新按钮的逻辑,那么将这段逻辑封送到UI线程中会不会解决问题呢?这里就不志关子了,实验是可以的。下面就贴出两种方案的示例代码,大家可以自行试验。

public ICommand SetWaitCommandExecuted
        {
            get
            {
                if (null == _setWaitCommandExecuted)
                    _setWaitCommandExecuted = new RelayCommand(() =>
                    {
                        Task.Run(() =>
                        {
                            ////window.Invoke(() =>
                            ////{
                            ////    //模拟一个耗时操作
                            ////    System.Threading.Thread.Sleep(1000);
                            ////    //方案一:在UI线程中更改
                            ////    CanWaitExecuted = true;
                            ////});

                            //System.Threading.Thread.Sleep(1000);
                            //CanWaitExecuted = true;
                            ////方案二:UI线程中进行强制刷新
                            //window.Invoke(CommandManager.InvalidateRequerySuggested);
                        });
                    });
                return _setWaitCommandExecuted;
            }
        }
时间: 2024-11-06 09:37:57

WPF中异步更新Command可用逻辑时按钮状态没有更新的相关文章

WPF中异步更新UI元素

XAML 界面很简单,只有一个按钮和一个lable元素,要实现点击button时,lable的内容从0开始自动递增. <Grid> <Label Name="lable_plus" Content="0"/> <Button Content="Button" Click="button_Click" Height="23" Name="button" Wid

WPF中的动画——(三)时间线(TimeLine)(转)

WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下几种TimeLine: AnimationTimeline :前面已经介绍过,主要用于属性的过渡,这种是最常见的动画. MediaTimeline:用于控制媒体文件播放的时间线. ParallelTimeline:ParallelTimeline 是一种可对其他时间线进行分组的时间线,可用于实现较复

WPF中的动画——(三)时间线(TimeLine)

时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下几种TimeLine: AnimationTimeline?:前面已经介绍过,主要用于属性的过渡,这种是最常见的动画. MediaTimeline:用于控制媒体文件播放的时间线. ParallelTimeline:ParallelTimeline?是一种可对其他时间线进行分组的时间线,可用于实现较复杂的动画. Storyboard?:一种特殊的?Pa

WPF中,使用ICollectionView进行排序时,汉字排序出现问题的解决

事情的起因是这样的,因为开发一个软件项目,其中用到了DataGrid控件,然后客户需要点击控件的列头,对内容进行排序,其实内容倒是蛮简单的(纯字符串),咋一看起来,实现应该很简单,应该直接将字符串进行排序显示就完了,于是就写成了类似于这样的代码(这里只是模拟一下,a只是简简单单的包含一个类型为string的公共属性s): a[] aas = new a[] { new a("scjaosinf"), new a("aedfbsdf"), new a("eg

WPF中的Visual Tree和Logical Tree与路由事件

1.Visual Tree和Logical TreeLogical Tree:逻辑树,WPF中用户界面有一个对象树构建而成,这棵树叫做逻辑树,元素的声明分层结构形成了所谓的逻辑树!!Visual Tree:可视树(也叫视觉树),可视树是对逻辑树的扩展,可视树将逻辑树的节点打散,分放到核心棵树组件中,它表述了一些详细的可视化实现,而不是把每个元素当做一个”黑盒“.我们以一个简单的程序来观察下逻辑树与可视树: <Window x:Class="WpfApplication28.MainWind

wpf 中使用 ttf

因为实现ImageButton接触ttf在wpf中的使用,ttf是图标按钮的集合文件.可在阿里www.iconfont.cn网站选择下载.首先选择所需图标添加到购物车,选择完成后从购物车中选择"下载代码",便可将其中的图标打包生成ttf文件并下载至本地.下载的文件夹中包含图一所示文件,其中iconfont.ttf是程序所需文件,打开该文件可看到"字体名称",程序根据该名称查找ttf文件,c#代码中的引用格式为"#"+"字体名称"

正确理解WPF中的TemplatedParent

(注:Logical Tree中文称为逻辑树,Visual Tree中文称为可视化树或者视觉树,由于名称不是很统一,文中统一用英文名称代表两个概念,况且VisualTreeHelper和LogicalTreeHelper也是WPF中提供的类名称) 众所周知WPF中的Logical Tree是逻辑上定义的元素层次树,而实际上显示在屏幕上的元素层次树是Visual Tree,Visual Tree是 (注:Logical Tree中文称为逻辑树,Visual Tree中文称为可视化树或者视觉树,由于

WPF中的Command命令详解

在WPF中使用命令的步骤很简单 1.创建命令 2.绑定命令 3.设置命令源 4.设置命令目标 WPF中命令的核心是System.Windows.Input.ICommand接口,所有命令对象都实现了此接口.当创建自己的命令时,不能直接实现ICommand接口,而是要使用System.Windows.Input.RouteCommand类,该类已经实现了ICommand接口,所有WPF命令都是RouteCommand类的实例.在程序中处理的大部分命令不是RoutedCommand对象,而是Rout

在WPF中减少逻辑与UI元素的耦合

原文:在WPF中减少逻辑与UI元素的耦合             在WPF中减少逻辑与UI元素的耦合 周银辉 1,    避免在逻辑中引用界面元素,别把后台数据强加给UI  一个糟糕的案例 比如说主界面上有一个显示当前任务状态的标签label_TaskState,我们会时常更新该标签以便及时地将任务状态通知用户.那么很糟糕的一种假设是我们的代码中会到处充斥着这样的语句段this.label_TaskState .Content = this.GetStateDescription(TaskSta