如何动态更新TextBlock控件中的文本(C# - WPF)

时间:2017-08-07 13:15:52

标签: c# dynamic textblock

我有一个名为Scroller的属性,如下所示。我有一个for循环,希望能够动态更新控件的内容。

我希望这个控件的内容能够刷新每个迭代次数。 此时,TextBlock在for ...循环存在且程序终止后显示内容。

我该怎么办?

 f <- function(x) {
  as.list(diff(x, lag=3)/x[1:3]*100)
}
df %>% 
  rowwise %>% 
  do(data.frame(perc = f(unlist(.)))
  ) %>% 
  bind_cols(df)
# Source: local data frame [50 x 9]
# Groups: <by row>
# 
# # A tibble: 50 x 9
#    perc.B.var.a perc.B.var.b perc.B.var.c A.var.a A.var.b A.var.c B.var.a B.var.b B.var.c
#           <dbl>        <dbl>        <dbl>   <int>   <int>   <int>   <int>   <int>   <int>
#  1   193.103448    380.00000    -56.66667      29       5      60      85      24      26
#  2   -36.708861    115.55556    -32.35294      79      45      34      50      97      23
#  3    -4.878049    -23.75000     22.44898      41      80      49      39      61      60
#  4   -71.910112    300.00000    -71.87500      89      13      96      25      52      27
#  5   -87.368421    -28.07018     10.20408      95      57      49      12      41      54
#  6   680.000000    323.80952    -12.22222       5      21      90      39      89      79
#  7     9.433962    184.61538    -81.52174      53      13      92      58      37      17
#  8   -75.555556    -61.84211    -32.78689      90      76      61      22      29      41
#  9   -19.642857    -80.00000     14.28571      56      90      42      45      18      48
# 10   -52.173913    -52.63158    480.00000      46      38      15      22      18      87
# # ... with 40 more rows

编辑:

我正在添加一个功能性解决方案来帮助演示我的问题。对不起,如果我的原始问题不够明确。

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Name="Scroller" Margin="0,90,0,57">
    <TextBlock x:Name="Output" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="{Binding ElementName=Scroller, Path=ViewportWidth}" TextWrapping="Wrap" Text="" />
</ScrollViewer>

以上是xaml文件,下面是代码。

<Window x:Class="RdElectReg.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:RdElectReg"
    mc:Ignorable="d" Height="350" Width="525">
<Grid>
    <Button x:Name="Start" Content="Start" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="419,56,23,0" Click="Button_Click" IsDefault="True"/>
    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Name="Scroller" Margin="0,90,0,57">
        <TextBlock x:Name="Output" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="{Binding ElementName=Scroller, Path=ViewportWidth}"
        TextWrapping="Wrap" Text="" />
    </ScrollViewer>
</Grid>

每次调用函数ProcessFile时,它都会获取TextBlock的内容,添加一些文本并更新TextBlock。

    using System.Text;
    using System.Windows;

    namespace RdElectReg
    {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i <= 10000; i++)
            {
                sb.Append(ProcessFile(i));
            }
        }

         private StringBuilder ProcessFile(int i)
        {
            StringBuilder sb1 = new StringBuilder();
            string TextBlockText = Output.Text;
            TextBlockText = TextBlockText + "Processing iteration " + i.ToString() + "\n";
            // this property
            Output.Text = TextBlockText;

            for (int j = 1; j < 1000; j++) {
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Remove(sb1.Length - 1, 1);
                sb1.AppendLine();
            }

            return sb1;
        }
    }
}

我的问题是在程序执行期间TextBlock不会动态更新。更新的文本仅在程序执行完后的格式中显示。

我希望TextBlock动态更新。

我希望这有助于澄清我的问题。

2 个答案:

答案 0 :(得分:0)

Output.Content = "foobar";

这是什么意思?

编辑:请添加更多代码,以便我们真正了解您在for循环中所做的事情。

答案 1 :(得分:0)

我设法找到了Updating value of TextBlock in wpf dynamically [Sovled]发布的解决方案。

这是修改后的解决方案(XAML):

<Window x:Class="RdElectReg.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:RdElectReg"
        mc:Ignorable="d" Height="350" Width="525">
    <Grid>
        <Button x:Name="Start" Content="Start" HorizontalAlignment="Center" VerticalAlignment="Top" Width="75" Margin="419,56,23,0" Click="Button_Click" IsDefault="True"/>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Name="Scroller" Margin="0,90,0,57">
            <TextBlock x:Name="Output" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="{Binding ElementName=Scroller, Path=ViewportWidth}"
        TextWrapping="Wrap" Text="{Binding Textstr}" />
        </ScrollViewer>
    </Grid>
</Window>

代码页(斜体代码显示了实现它的其他说明):

using System.Text;
*using System.Threading;*
using System.Windows;

namespace RdElectReg
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        *Progress viewModel = new Progress();*

        public MainWindow()
        {
            InitializeComponent();
            *this.DataContext = viewModel;*
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            */// Background thread Thread to run your logic 
            Thread thread = new Thread(YourLogicToUpdateTextBlock);
            thread.IsBackground = true;
            thread.Start();*
        }
        *// https://stackoverflow.com/questions/38477276/updating-value-of-textblock-in-wpf-dynamically-sovled*
        private void YourLogicToUpdateTextBlock()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i <= 1000; i++)
            {
                viewModel.Textstr = viewModel.Textstr + "Processing iteration " + i.ToString() + "\n";
                sb.Append(ProcessFile(i));
            }
            viewModel.Textstr = viewModel.Textstr + "DONE\n";
        }

        private StringBuilder ProcessFile(int i)
        {
            StringBuilder sb1 = new StringBuilder();

            for (int j = 1; j < 10000; j++) {
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Append(j.ToString() + ",");
                sb1.Remove(sb1.Length - 1, 1);
                sb1.AppendLine();
            }

            return sb1;
        }
    }
}

类Progress被数据绑定到文本块。课程如下:

using System.ComponentModel;

namespace RdElectReg
{
    class Progress : INotifyPropertyChanged
    {
        private string _textstr = "";

        public Progress()
        {
            _textstr = "";
        }

        public Progress(string text)
        {
            _textstr = text;
        }

        public string Textstr
        {
            get
            {
                return _textstr;
            }
            set
            {
                _textstr = value;
                OnPropertyChanged("Textstr");
            }
        }

        // property changed event
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string PropertyName)
        {
            if (this.PropertyChanged != null)
            {
                // Raise the PropertyChanged event
                this.PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

     }
}

我对解决方案的解释是:

  1. TextBlock是绑定到类Progress
  2. 的属性Textstr的数据
  3. 该类在代码中实例化并使用this.DataContext比较丰富的TextBlock
  4. 解决方案的主要逻辑(在我的案例中最初是Button_Click)作为后台线程执行。