<Window.Resources>
<Style x:Key="NormalStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#FF007ACC" />
</Style>
<Style x:Key="LoadDataStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#9333FF" />
</Style>
<Style x:Key="ErrorStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#eb4034" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Menu VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem
x:Name="LoadDataToDB"
Click="LoadDataToDB_Click"
Header="LoadDataToDB" />
</MenuItem>
</Menu>
<DockPanel x:Name="StatusBar" Grid.Row="1" Style="{StaticResource LoadDataStatusBar}"> <!--Style меняться во время выполнения LoadDataInDB()-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="DataStatus"
Grid.Column="0"
Margin="10,0,0,0"
Foreground="White"
Text="Статус данных" />
<DockPanel Grid.Column="1" HorizontalAlignment="Right">
<TextBlock
x:Name="CurrnetLine"
Margin="0,0,5,0"
Foreground="White"
Text="{Binding currentLine}" /> <!--должно меняться во время выполнения LoadDataInDB()-->
<TextBlock
Margin="0,0,5,0"
Foreground="White"
Text="/" />
<TextBlock
x:Name="MaxLines"
Margin="0,0,10,0"
Foreground="White"
Text="{Binding maxLines}" />
</DockPanel>
</Grid>
</DockPanel>
</Grid>
public string maxLines { get; set; }
public string currentLine { get; set; }
Style normalBarStyle;
Style LoadBarStyle;
Style errorBarStyle;
public MainWindow()
{
InitializeComponent();
normalBarStyle = this.FindResource("NormalStatusBar") as Style;
LoadBarStyle = this.FindResource("LoadDataStatusBar") as Style;
errorBarStyle = this.FindResource("ErrorStatusBar") as Style;
StatusBar.Style = normalBarStyle;
DataContext = this;
}
private void LoadDataToDB_Click(object sender, RoutedEventArgs e)
{
StatusBar.Style = LoadBarStyle;
Mouse.OverrideCursor = Cursors.Wait;
Analyzer analyzer = new Analyzer();
analyzer.LoadDataInDB(this);//вызываю метод который делает приложение не активным
Mouse.OverrideCursor = Cursors.Arrow;
StatusBar.Style = normalBarStyle;
}
public event PropertyChangedEventHandler PropertyChanged;
public void ChangeLineData()
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(maxLines)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(currentLine)));
}
if (запрос к бд == true) {
DataBase.ClearAll();
DirectoryInfo info = new DirectoryInfo(@"path\Data\");
DirectoryInfo[] dirs = info.GetDirectories();
for (int r = 0; r < dirs.Length; r++) {
var additionalLines = File.ReadAllLines(@"path\Data\" + dirs[r].Name + @"\
Additional.txt "); ~ 10000строк
var mainLines = File.ReadAllLines(@"pathr\Data\" + dirs[r].Name + @"\
Main.txt "); ~ 18000строк
for (int i = 0; i < mainLines.Length; i++) {
DataMain data = new DataMain(); //обычный класс с переменными
int markCounter = 0; //слова отделяются символом '!'
string word = string.Empty;
for (int j = 0; j < mainLines[i].Length; j++) {
char symbol = mainLines[i][j];
mainWindow.maxLines = mainLines.Length.ToString(); //общие количество линий
mainWindow.currentLine = i.ToString(); //текущая линя
mainWindow.ChangeLineData(); //вызываю метод для смены данных bining полей
if (symbol == '!') { //если символ равен разделителю слов
switch (markCounter) {
case 2: //если второе слово, то заполнятся это:
data.Alpha = Convert.ToInt32(word);
break;
case 1: //и дальше тем же методом
data.Bravo = long.Parse(word);
break;
case 0:
data.Charlie = ConvertToInt(word);
break;
case 5:
data.Delta = ConvertToInt(word);
break;
case 6:
data.Echo = ConvertToInt(word);
break;
case 7:
data.Foxtrot = ConvertToInt(word);
break;
case 10:
data.Golf = ConvertToInt(word);
break;
case 11:
data.Hotel = ConvertToInt(word);
break;
}
word = string.Empty;//очистка переменной
markCounter++;// +1 к счетчику разделителей
} else { //иначе добавляется символ к слову
word += symbol.ToString();
}
}
DataBase.AddMainData(data); // вызов хранимой процедуры с параметрами
}
for (int i = 0; i < additionalLines.Length; i++) {
//тут все тоже самое только в DataAdditional полей в раза 3-4 больше.
}
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ProgressBarExample
{
internal class Analyzer
{
private readonly SynchronizationContext _synchronizationContext;
public Analyzer()
{
// Если экземпляр класса будет создан в UI потоке,
// то здесь будет контекст синхронизации UI потока, иначе пула потоков
_synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
}
public event EventHandler<AnalyzerEventArgs> ProgressChanged;
public async Task<Data> LoadDataInDB()
{
var result = await Task.Run(async () =>
{
for (int i = 0; i < 100; i++)
{
await Task.Delay(250);
OnProgressChanged(new AnalyzerEventArgs("line " + (i + 1), 100));
}
return new Data() { Text = "Данные " };
});
return result;
}
private void OnProgressChanged(AnalyzerEventArgs args)
{
// Перенаправляем выполнение в UI поток не ожидая пока отработает метод обработчик события.
_synchronizationContext.Post(state =>
{
ProgressChanged?.Invoke(this, (AnalyzerEventArgs)state);
}, args); // args передаётся в переменную state (грубо говоря)
}
}
}
namespace ProgressBarExample
{
public class AnalyzerEventArgs
{
public int MaxLines { get; }
public string CurrentLine { get; }
public AnalyzerEventArgs(string currentLine, int maxLines)
{
CurrentLine = currentLine;
MaxLines = maxLines;
}
}
}
namespace ProgressBarExample
{
public class Data
{
public string Text { get; set; }
}
}
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace ProgressBarExample
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private readonly Analyzer _analyzer;
private readonly Style _normalBarStyle;
private readonly Style _loadBarStyle;
private readonly Style _errorBarStyle;
private string _maxLines;
private string _currentLine;
public string MaxLines
{
get { return _maxLines; }
set
{
_maxLines = value;
OnPropertyChanged();
}
}
public string CurrentLine
{
get { return _currentLine; }
set
{
_currentLine = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
InitializeComponent();
_normalBarStyle = FindResource("NormalStatusBar") as Style;
_loadBarStyle = FindResource("LoadDataStatusBar") as Style;
_errorBarStyle = FindResource("ErrorStatusBar") as Style;
_statusBar.Style = _normalBarStyle;
_analyzer = new Analyzer();
_analyzer.ProgressChanged += OnAnalyzerProgressChanged;
}
private void OnAnalyzerProgressChanged(object sender, AnalyzerEventArgs args)
{
// Передавать каждый раз одно и тоже бессмысленно, сделаете сами как нужно
MaxLines = args.MaxLines.ToString();
CurrentLine = args.CurrentLine;
}
private async void LoadDataToDB_Click(object sender, RoutedEventArgs e)
{
_statusBar.Style = _loadBarStyle;
Mouse.OverrideCursor = Cursors.Wait;
try
{
var data = await _analyzer.LoadDataInDB();
MessageBox.Show(data.Text);
}
finally
{
Mouse.OverrideCursor = Cursors.Arrow;
_statusBar.Style = _normalBarStyle;
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<Window
x:Class="ProgressBarExample.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:local="clr-namespace:ProgressBarExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d">
<Window.Resources>
<Style x:Key="NormalStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#FF007ACC" />
</Style>
<Style x:Key="LoadDataStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#9333FF" />
</Style>
<Style x:Key="ErrorStatusBar" TargetType="DockPanel">
<Setter Property="Background" Value="#eb4034" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Menu VerticalAlignment="Top">
<MenuItem Header="File">
<MenuItem
x:Name="LoadDataToDB"
Click="LoadDataToDB_Click"
Header="LoadDataToDB" />
</MenuItem>
</Menu>
<DockPanel
x:Name="_statusBar"
Grid.Row="1"
Style="{StaticResource LoadDataStatusBar}">
<!-- Style меняться во время выполнения LoadDataInDB() -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="10,0,0,0"
Foreground="White"
Text="Статус данных" />
<DockPanel Grid.Column="1" HorizontalAlignment="Right">
<TextBlock
Margin="0,0,5,0"
Foreground="White"
Text="{Binding CurrentLine}" />
<!-- должно меняться во время выполнения LoadDataInDB() -->
<TextBlock
Margin="0,0,5,0"
Foreground="White"
Text="/" />
<TextBlock
Margin="0,0,10,0"
Foreground="White"
Text="{Binding MaxLines}" />
</DockPanel>
</Grid>
</DockPanel>
</Grid>
</Window>