【问题标题】:Updating progress in TextBlock using background thread使用后台线程更新 TextBlock 中的进度
【发布时间】:2013-06-14 12:03:44
【问题描述】:

我的 WPF 窗口有一个封装在 ScrollViewer 中的 TextBlock。

<Window x:Class="WpfScrollProgress.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="545" Width="662"
    Loaded="OnLoad">
    <Grid>
        <Label Content="Please wait while the items are being processed" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="lblStatus" VerticalAlignment="Top" Width="263" />
        <ScrollViewer Name="ScrollViewer1" Margin="10,46,0,136">
            <TextBlock Height="293" HorizontalAlignment="Left" Margin="10,15,10,100" Name="txtStatus" Text="" VerticalAlignment="Top" Width="574" Canvas.Left="-9" />
        </ScrollViewer>
    </Grid>
</Window>

我正在尝试使用后台线程更新进度状态。但是,当文本块中的状态更新时,滚动操作似乎不起作用

using System;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace WpfScrollProgress
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        private void OnLoad(System.Object sender, System.Windows.RoutedEventArgs e)
        {
            Action<object> oProgressAction = (object s) => { RefreshProgressStatus((string)s); };
            ProgressReporter oProgressReporter = new ProgressReporter(TaskScheduler.FromCurrentSynchronizationContext(), oProgressAction);

            Task.Factory.StartNew(() =>
            {
                for (int i = 0; i <= 100; i++)
                {
                    oProgressReporter.ReportProgress("Hello " + i);
                    Thread.Sleep(100);
                }
            });
        }

        public void RefreshProgressStatus(string strUpdate)
        {
            txtStatus.Text = txtStatus.Text  + strUpdate + "............" + Environment.NewLine;
        }

    }

    public class ProgressReporter
    {

        private TaskScheduler _oScheduler;
        private string _strStatus;

        private Action<object> _oProgressAction;
        public ProgressReporter(TaskScheduler oScheduler, Action<object> oProgressAction)
        {
            _oScheduler = oScheduler;
            _oProgressAction = oProgressAction;
        }

        public TaskScheduler Scheduler
        {
            get { return _oScheduler; }
        }

        private Task ReportProgressAsync(Action<object> action)
        {
            return Task.Factory.StartNew(action, _strStatus, CancellationToken.None, TaskCreationOptions.None, this.Scheduler);
        }

        public void ReportProgress(string strStatus)
        {
            _strStatus = strStatus + "..........." ;
            this.ReportProgressAsync(_oProgressAction).Wait();
        }

    }

}

滚动操作似乎在 ScrollViewer 上不起作用,并且 TextBlock 内容不会显示在 ScrollViewer 之外。这里有什么遗漏吗?

【问题讨论】:

  • 我会尝试使用基本的BackgroundWorker 并首先通过Dispatcher 进行进度通知,看看这是否有效。我也不明白这个....Thread.Sleep(100);.
  • Thread.Sleep 会在此过程中短暂暂停。即使没有它也没有任何区别。
  • @WPF-it。代码有效并且文本块被更新直到滚动区域。除此之外它没有。我觉得它与 WPF 重新分页有关。

标签: c# wpf task-parallel-library


【解决方案1】:

您的 TextBlock 具有固定的 WidthHeight。它不会延伸/增长超出此范围。如果您的文本占用的空间比 Textblock 的 Width 多,则会被裁剪。

删除HeightWidth 属性。

我建议您阅读基本的 WPF 布局/设计概念,以及如何通过 DataBinding 正确更新 UI 元素属性,而不是使用程序代码。

【讨论】:

  • 感谢@HighCore。删除宽度和高度就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 1970-01-01
  • 2014-04-18
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多