【问题标题】:How to update the value of progressbar and textblock in wpf如何在wpf中更新进度条和文本块的值
【发布时间】:2014-08-25 07:35:30
【问题描述】:

我是 wpf 和 c# 的新手,也在这里提问。我在网上搜索了几个小时,但我还没有找到解决问题的方法。我有一个进度条,可以在循环增加时更新它的值,还有一个更新它的文本的文本块(例如:Reading Lines 5/3000)。目前,我没有绑定路径,所以我在我的 xaml 中进行了虚拟绑定。我不知道如何让它工作。

这是我的 XAML:

<xctk:BusyIndicator x:Name="_busyIndicator" Grid.Row="4">
                <xctk:BusyIndicator.BusyContentTemplate>
                    <DataTemplate>
                        <StackPanel Margin="4">
                            <TextBlock Text="Parsing OTM File" FontWeight="Bold" HorizontalAlignment="Center" />
                            <StackPanel Margin="4">
                                <TextBlock Text="{Binding NumberOfLinesOfStringInTextFile}" />
                                <ProgressBar Grid.Row="4" Name="prgParse" Height="15" Value="{Binding CurrentLineNumberAddedToListView}" />
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </xctk:BusyIndicator.BusyContentTemplate>
                <xctk:BusyIndicator.OverlayStyle>
                    <Style TargetType="Rectangle">
                        <Setter Property="Fill" Value="#ffffeeee"/>
                    </Style>
                </xctk:BusyIndicator.OverlayStyle>
                <xctk:BusyIndicator.ProgressBarStyle>
                    <Style TargetType="ProgressBar">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </Style>
                </xctk:BusyIndicator.ProgressBarStyle>
                <ListBox x:Name="_listBox" />
            </xctk:BusyIndicator>

我有一个按钮触发读取文本文件中的行(在本例中它有 3000 多行)并将字符串行放置到列表视图中的循环。我想更新我的 xaml 中的文本块,该文本块指出“正在阅读第 300/3000 行”,进度条指示它的百分比,在将数据传输到列表视图时将其值更新为 10 或 10%。

这是我的代码:

 public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

        }

        private void cmdBrowse_Click(object sender, RoutedEventArgs e)
        {

            var OpenOTM = new Microsoft.Win32.OpenFileDialog();
            OpenOTM.DefaultExt = ".otm";
            OpenOTM.Filter = "OTM Files (*.otm)|*.otm|TEXT Files (*.txt)|*.txt"; 

            if (OpenOTM.ShowDialog().GetValueOrDefault(false))
            {
                txtFilePath.Text = OpenOTM.FileName;
            }
        }

        private void cmdOk_Click(object sender, RoutedEventArgs e)
        {
            WithAdjustments wa = new WithAdjustments();
            BackgroundWorker worker = new BackgroundWorker();

            string[] lines = System.IO.File.ReadAllLines(txtFilePath.Text);
            worker.DoWork += (o, ea) =>
            {
                List<String> listOfString = new List<string>();
                foreach (string lin in lines)
                {
                    listOfString.Add(lin);
                    Thread.Sleep(2);
                }

                Dispatcher.Invoke((Action)(() => _listBox.ItemsSource = listOfString));
            };
            worker.RunWorkerCompleted += (o, ea) =>
            {
                _busyIndicator.IsBusy = false;
            };
            _busyIndicator.IsBusy = true;
            worker.RunWorkerAsync();
        }
    }

提前致谢!我希望有人可以帮助我:)

【问题讨论】:

    标签: c# wpf binding progress-bar busyindicator


    【解决方案1】:

    您可以使用后台工作器报告进度回调更新您的属性 CurrentLineNumberAddedToListView、NumberOfLinesOfStringInTextFile,

    worker.WorkerSupportsCancellation = true;
    worker.WorkerReportsProgress = true;
    
    worker.ProgressChanged += (o, e) =>
    {
         //Here in e.ProgressPercentage you will get the current line number read you can deduct the textblock text and progressbar value to be set on CurrentLineNumberAddedToListView and NumberOfLinesOfStringInTextFile
    }
    
    worker.DoWork += (o, ea) =>
            {
                List<String> listOfString = new List<string>();
                BackgroundWorker worker = o as BackgroundWorker;
                int numberofLine = 0;
                foreach (string lin in lines)
                {
                    listOfString.Add(lin);
    
                    o.ReportProgress(++numberofLine);
                    Thread.Sleep(2);
                }
    
    
                Dispatcher.Invoke((Action)(() => _listBox.ItemsSource = listOfString));
            };
    

    【讨论】:

    • 嗨先生@nit我在这里完全是一个菜鸟,我很抱歉,但我不明白或者我不知道如何做到这一点“//这里在e.ProgressPercentage您将获得读取的当前行号,您可以扣除要在 CurrentLineNumberAddedToListView 和 NumberOfLinesOfStringInTextFile 上设置的文本块文本和进度条值。顺便说一句,非常感谢你给我一个想法:)
    【解决方案2】:

    也许这可以帮助您的 ProgressBar:

    Private Sub InitProgressBar(ByVal DblMaximumValueI As Double)
        'set min and max
        ProgressBar1.Minimum = 0
        ProgressBar1.Maximum = DblMaximumValueI
        'set start value
        ProgressBar1.Value = 0
    End Sub
    
    Private Sub IncremenetProgressBar_()
        ProgressBar1.Value += 1 'or variable
    End Sub
    

    并在下面调用 sub 以显示进度:

    Public Sub IncrementProgressBar()
       Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(AddressOf IncremenetProgressBar_))
    End Sub
    

    要更新您的 TextBlock,您可以添加如下模块:

    Module ExtensionMethods
    'anonymous delegates are not allowed in VB.NET, so we need an empty method
    Private Sub EmptyMethod()
    
    End Sub
    
    'refresh for Controls
    <Extension()> _
    Public Sub Refresh(ByVal uiElement As UIElement)
        uiElement.Dispatcher.Invoke(DispatcherPriority.Render, New Action(AddressOf EmptyMethod))
    End Sub
    
    End Module
    

    然后在设置TextBloxName.Text后调用TextBloxName.Refresh

    【讨论】:

    • 我讨厌投反对票,但问题是在 C# 中,这是一个 .vb 答案。
    • 哦,谢谢。所以你对我投了反对票,因为我试图提供帮助而我不会写 c#?您是否认为没有答案比另一种语言更好!?还是我应该请人帮我翻译?其他人对此有何看法?即使我不太懂这种语言,我也会很高兴收到 C# 答案。
    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    相关资源
    最近更新 更多