我如何刷新循环内设置可视控件属性(TextBlock.text)? [英] How do I refresh visual control properties (TextBlock.text) set inside a loop?

查看:595
本文介绍了我如何刷新循环内设置可视控件属性(TextBlock.text)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着每次循环迭代我想在视觉上更新TextBlock的文本。我的问题是WPF窗口或控件不直观刷新,直到循环完成。

With each loop iteration I want to visually update the text of a textblock. My problem is the WPF window or control does not visually refresh until the loop is complete.

        for (int i = 0; i < 50; i++)
        {
            System.Threading.Thread.Sleep(100);
            myTextBlock.Text = i.ToString();                
        }

在VB6我所说的DoEvents()或co​​ntrol.refresh。此刻,我只想一个快速和肮脏的解决方案类似的DoEvents(),但我也想知道的替代品或正确的方式做到这一点。有没有我可以添加一个简单的绑定声明?什么是语法?
先谢谢了。

In VB6 I would call DoEvents() or control.refresh. At the moment I'd just like a quick and dirty solution similar to DoEvents(), but I'd also like to know about alternatives or the "right" way to do this. Is there a simple binding statement I could add? What is the syntax? Thanks in advance.

推荐答案

如果您的真正的希望快速和肮脏的执行情况,并不在乎在未来或对用户体验的维护产品,你可以添加到System.Windows.Forms的和呼叫 System.Windows.Forms.Application.DoEvents()的参考

If you really want the quick and dirty implementation and don't care about maintaining the product in the future or about the user experience, you can just add a reference to System.Windows.Forms and call System.Windows.Forms.Application.DoEvents():

for (int i = 0; i < 50; i++)
{
    System.Threading.Thread.Sleep(100);
    MyTextBlock.Text = i.ToString();
    System.Windows.Forms.Application.DoEvents();
}

缺点是,它的真的很糟糕。你会Thread.sleep代码(),这惹恼用户在锁定了用户界面,你可以用这取决于程序的复杂性未predictable结果落得(我见过一个应用程序,其中的两种方法在UI线程上运行了,每一个调用DoEvents()反复...)。

The downside is that it's really really bad. You're going to lock up the UI during the Thread.Sleep(), which annoys the user, and you could end up with unpredictable results depending on the complexity of the program (I have seen one application where two methods were running on the UI thread, each one calling DoEvents() repeatedly...).


  1. 您的应用程序必须等待一些事情发生(即磁盘读取,Web服务调用,或睡眠())的任何时间,应该是在一个单独的线程。

  2. 您不能手动设置TextBlock.Text - 其绑定到一个属性,实现INotifyPropertyChanged

下面是显示你要求的功能的示例。只需要几秒钟来写,它是这么多更容易使用 - 它不会锁定用户界面

Here is an example showing the functionality you've asked for. It only takes a few seconds longer to write and it's so much easier to work with - and it doesn't lock up the UI.

的XAML:

<StackPanel>
    <TextBlock Name="MyTextBlock" Text="{Binding Path=MyValue}"></TextBlock>
    <Button Click="Button_Click">OK</Button>
</StackPanel>

codeBehind:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 50; i++)
            {
                System.Threading.Thread.Sleep(100);
                MyValue = i.ToString();
            }
        });
    }

    private string myValue;
    public string MyValue
    {
        get { return myValue; }
        set
        {
            myValue = value;
            RaisePropertyChanged("MyValue");
        }
    }

    private void RaisePropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

在code似乎有点复杂,但它是WPF的基石,并将其与一些练习来一起 - 这是值得我们学习

The code might seem a bit complicated, but it's a cornerstone of WPF, and it comes together with a bit of practice - it's well worth learning.

这篇关于我如何刷新循环内设置可视控件属性(TextBlock.text)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆