Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程繁忙时WPF重画窗口_C#_Wpf - Fatal编程技术网

C# 线程繁忙时WPF重画窗口

C# 线程繁忙时WPF重画窗口,c#,wpf,C#,Wpf,下面是我问题的简短示例。 在函数开始时,我想更改一些视觉参数,例如 隐藏窗口,使其变为红色(“我的示例”),在函数末尾,我想将其放回原处。 一些东西,如鼠标,等待光标的长期功能 在按钮单击功能结束之前,有没有优雅的方法使按钮变红- 允许窗口消息循环并行处理请求Background=Red并立即重画窗口的方法 private void OnButtonClick(object sender, RoutedEventArgs e) { System.W

下面是我问题的简短示例。 在函数开始时,我想更改一些视觉参数,例如 隐藏窗口,使其变为红色(“我的示例”),在函数末尾,我想将其放回原处。 一些东西,如鼠标,等待光标的长期功能

在按钮单击功能结束之前,有没有优雅的方法使按钮变红- 允许窗口消息循环并行处理请求Background=Red并立即重画窗口的方法

private void OnButtonClick(object sender, RoutedEventArgs e)
{            
            System.Windows.Media.Brush br = ((Button)sender).Background;
            ((Button)sender).Background = System.Windows.Media.Brushes.Red;

            Mouse.OverrideCursor = Cursors.Wait;
            Function(); //long-term function 
            Mouse.OverrideCursor = Cursors.Arrow;

            ((Button)sender).Background = br;                  
}

您可以在新线程中运行它,可以是后台工作线程,也可以使用任务并行库(见下文)


如果您使用的是.NET 4.5,也可以使用Async/Await关键字来完成此操作。

有一种简单的方法来完成此操作。
xaml:


您的问题是什么?将
函数()
放在另一个线程中,例如使用
backgroundworker
谢谢,但是这不是我想要的,或者可能是另一个问题:我不希望用户单击另一个按钮并与窗口交互。长时间运行的函数没有那么长,最初我只使用等待光标,现在我只想给用户一个关于繁忙窗口的更好的视觉信息。对于后台任务,用户并不是很忙。您的问题要求以“并行”方式运行函数()。老实说,我认为这个答案完美地回答了这个问题。如果您有不同的问题,请开始新的问题,而不是在人们花时间回答后更改此问题。@user2136076,然后您可以尝试此扩展方法:Benjamin,我感谢Task的想法,尤其是您为帮助我们所做的努力。但我试过了,它并没有完全符合我的要求。QEstion是以并行方式更改颜色的,而不是运行函数()。第二个问题并不是第一个问题的改变,而是为了你,如果你知道如何继续解决任务解决方案的不足。是我的错,这个问题问得不好。Bolu引导我找到了我一直在寻找的解决方案。谢谢大家。这个解决方案很好,但可能会遇到时间问题。我认为最好使用Invoke代替BeginInvoke,以确保它立即运行。感谢@MarkTravis的建议,我已经更新了答案。@MarkTravis
Invoke
不能保证立即启动委托,但它会阻止调用线程,直到调度程序线程为委托提供服务为止-它是同步运行的。
private void OnButtonClick(object sender, RoutedEventArgs e)
{            
            System.Windows.Media.Brush br = ((Button)sender).Background;
            ((Button)sender).Background = System.Windows.Media.Brushes.Red;

            Mouse.OverrideCursor = Cursors.Wait;

            // Run function in a new thread.
            Task.Factory.StartNew(() =>
            {
                Function(); // Long running function.
            })
            .ContinueWith((result) =>
                {
                    // Runs when Function is complete...
                    Mouse.OverrideCursor = Cursors.Arrow;
                    ((Button)sender).Background = br;       
                }); 


}
<Button Command="{Binding TestCommand}" Content="Test" Focusable="False" Background="Green">
    <Button.Resources>
        <Style TargetType="Button">
            <Style.Triggers>
               <DataTrigger Binding="{Binding Loading}" Value="true">
                   <Setter Property="Background" Value="Red"/>
               </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Resources>
</Button>  
public class VM : INotifyPropertyChanged
{
    public bool Loading
    {
        get { return _loading; }
        private set
        {
            if (value.Equals(_loading)) return;
            _loading = value;
            OnPropertyChanged("Loading");
        }
    }
    public RelayCommand TestCommand
    {
        get { return _testCommand; }
    }

    void Test(object parameter)
    {
        Dispatcher.CurrentDispatcher.BeginInvoke( (Action) (() => Loading = true));
        //or if you want to do it with more responsive UI then use
        Dispatcher.CurrentDispatcher.Invoke( (Action) (() => Loading = true));
        doSomething(); //this could be replaced with BackgroundWorker DoWork function  
        //or this code could be the DoWork function.
        Loading = false;
    }
}