首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IsEnabled = false;//非“立即”

IsEnabled = false;//非“立即”
EN

Stack Overflow用户
提问于 2013-07-09 02:17:43
回答 3查看 709关注 0票数 1

我有这样的东西:

代码语言:javascript
复制
void ClickHandler() // Called from several places
{  // Try to prevent queuing accidental extra clicks during lengthy operation
    GetMainWindow().IsEnabled = false; // "GetMainWindow()" you know what I mean
    DoLengthyStuffInThisThread(); // Yes, I know I shouldnt
    PresentResult();
    GetMainWindow().IsEnabled = true;  
}

基本上就是这样。不过要澄清的是:

即使我设置了IsEnabled = false,它也没有达到预期的效果,我的额外点击会在操作过程中发生。(如果我返回时没有恢复该值,则会产生影响。)我假设正常情况下我的线程需要返回才能使禁用生效,但我不希望创建额外的线程。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-09 23:01:12

感谢大家的回答。最好的答案实际上是在威尔·埃丁斯的一部*comments,中。额外的thanks!*

对我这个令人难以置信的问题的回答是:System.Windows.Forms.Application.DoEvents();

虽然不是很好看,但这是我不得不做的。孩子们,不要在家里尝试!

代码语言:javascript
复制
  public void WrapLengthyWork(Action lengthyWork)
    {
        SetWaiting(true);
        System.Windows.Forms.Application.DoEvents();
        lengthy(); 
        SetWaiting(false);
    }

    public void SetWaiting(bool wait)
    {
        if (wait == true)
        {
            Mouse.OverrideCursor = Cursors.Wait;
            Application.Current.MainWindow.IsEnabled = false;
       }
        else
        {
            IsEnabled = true;
            Mouse.OverrideCursor = Cursors.Arrow;
        }
    }

另外,对于所有建议我正确使用线程切换的人:也感谢你们。我(正如我提到的)痛苦地意识到上述代码片段是糟糕的编码风格。我的问题是"LengthyWork()“本身充满了引用回图形用户界面的东西,并且必须在图形用户界面线程中运行,例如:

代码语言:javascript
复制
while(stuffToDo)
{
    Fetch();
    Calculate();
    UpdateGUI();
}

考虑到强加的时间限制(几个小时)和有限的任务(“防止在处理过程中点击,并显示等待-光标和触摸没有其他”),不幸的是,适当的解决方案不是一个选择。

票数 0
EN

Stack Overflow用户

发布于 2013-07-09 02:19:49

你必须将冗长的工作转移给另一个线程。直到封闭方法完成之后,UI才会收到此更改的通知(因此,没有机会使用布局通道刷新其状态)。

我可以想象,在这个冗长的方法中发生的任何事情都是在操作UI上显示的一些数据。如果您正在使用数据绑定,此操作将在后台填充UI (如果它在后台线程上运行),然后当该操作完成时,它可以告诉UI重新启用自身。

这是半伪代码,但请查看Task.Factory.StartNew和Dispatcher.BeginInvoke。

代码语言:javascript
复制
public void ClickHandler()
    {
        MainWindow.IsEnabled = false;

        Task.Factory.StartNew(() =>
            {
                // Length work goes here
            }).ContinueWith((result) =>
                {
                    Dispatcher.BeginInvoke(() =>
                        {
                            MainWindow.IsEnabled = true;
                        });
                });
    }
票数 2
EN

Stack Overflow用户

发布于 2013-07-09 02:25:38

@william-custode是对的,你应该在主应用程序线程上做繁重的工作。但是,解决方法是在开始"DoLengthyStuffInThisThread“之前使用forcing the window's message loop to consume all currently dispatched messages

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17533352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档