在程序期间强制更新视觉

时间:2016-01-04 09:52:28

标签: c# wpf

我尝试了很多东西,但没有一个正在发挥作用。 让我解释一下:

这就是我的应用程序的工作方式:我点击按钮,它使用http请求调用方法。 请求都是同步的。

button click - >将loading visual设为Visible - > http request使用相同的方法 - > http request finished - >将loading visual设为Collapsed

这是代码示例:

    public static StackPanel loading ;

    public static void setLoading()
    {
        MyStaticValues.loading.Visibility = Visibility.Visible;
        MyStaticValues.loading.UpdateLayout();
    }

    public static void setUnLoading()
    {
        MyStaticValues.loading.Visibility = Visibility.Collapsed;
        MyStaticValues.loading.UpdateLayout();
    }

...

        MyStaticValues.loading = this.spinner;
        MyStaticValues.loading.InvalidateVisual();


... 

...

// http request method -on click- 
    MyStaticValues.setLoading();
    ..do HTTP request..
    // after success ->
    MyStaticValues.setUnLoading();

..end..

它总是进入setLoading / setUnLoading方法,但UI永远不会刷新。 正如我所说,请求都是同步的。 问题可能来自于此,但我想尽可能保持请求同步..

任何想法?

2 个答案:

答案 0 :(得分:0)

问题是您在处理UI请求时正在执行三种方法(setLoading,do http和setUnloading)。这是在唯一的UI线程上完成的。

在您从按钮点击事件返回之前,没有重新绘制或绘画。

要获得所需的效果,您必须以异步方式执行http加载:

protected override void OnClick(object sender, EventArgs args)
{
   Thread worker = new Thread(HandleOnClick);
   worker.Start();
}

private void HandleOnClick()
{
    Invoke(setLoading); // this will execute on the UI thread
    // do http stuff this happens when you do it

    Invoke(setUnloading); // This will execute on the UI thread as well
}

答案 1 :(得分:0)

如果要使应用程序尽可能保持同步,可以在WPF中模拟Windows窗体的DoEvents方法。 你只需要一个简单的帮助类:

public class UIHelper
{
    private delegate void VoidHandler();

    public static void DoEvents()
    {
        Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new VoidHandler(delegate { }));
    }
}

然后在您的点击事件处理程序中,您可以编写类似的内容:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button button = (Button)sender;
    button.Content = "I'm starting to perform a long task!";

    UIHelper.DoEvents();

    // Next code line simulate your synchronous http request
    // Let's suppose it lasts 10 seconds...
    Thread.Sleep(1000 * 10);

    button.Content = "I'm ok now!";
}

这不是我最喜欢的解决方案 - 我同意异步http请求会更好 - 但它允许您保持应用程序同步。