Как обновить значение индикатора выполнения и текстового блока в wpf

Я новичок в wpf и С#, а также спрашиваю здесь. Я ищу в Интернете в течение нескольких часов, и я не нашел решения для моей проблемы. У меня есть индикатор выполнения, который обновляет свое значение всякий раз, когда цикл увеличивается, и текстовый блок, который обновляет его текст (например, строки чтения 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();
        }
    }

Заранее спасибо! Я надеюсь, что кто-то может мне помочь :)


person Beginner Programmer    schedule 04.07.2014    source источник


Ответы (2)


Вы можете обновить свои свойства 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));
        };
person Nitin    schedule 04.07.2014
comment
привет, сэр @nit, я здесь полностью и буквально нуб, извините, но я не понял или не знаю, как это сделать // Здесь, в e.ProgressPercentage, вы получите текущий номер строки, прочитанный вами может вычитать текст текстового блока и значение индикатора выполнения, которые должны быть установлены в CurrentLineNumberAddedToListView и NumberOfLinesOfStringInTextFile. Кстати, большое спасибо за идею :) - person Beginner Programmer; 04.07.2014

Возможно, это может помочь вам с вашим 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.Refresh после установки TextBloxName.Text

person Crow1973    schedule 04.07.2014
comment
Я ненавижу понижать голос, но вопрос на С#, и это ответ .vb. - person Perchik; 10.06.2015
comment
О, спасибо. Итак, вы минусуете меня, потому что я пытался помочь, но не умею писать на С#? Вы думаете, что нет ответа лучше, чем ответ на другом языке!? Или я должен попросить кого-нибудь перевести это для меня? Что другие люди думают об этом? Я был бы рад получить ответ на С#, даже если я плохо знаю этот язык. - person Crow1973; 15.06.2015