1.    нужно добавить кнопку для загрузки файлов расширения .magnete
2.  она делает все тоже самое что и кнопка для txt
3.  добавить еще одно окно для просмотра .magnete

вообщем все тоже самое что и для txt только для mfgnete


<Window x:Class="TxtProcessorApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TxtProcessorApp"
        Title="Txt Processor" Height="600" Width="900">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- Кнопка загрузки файлов -->
        <Button Content="Загрузить .txt файлы" Width="150" Height="30" Click="LoadFiles_Click"/>

        <!-- TabControl для отображения данных из файлов -->
        <TabControl x:Name="FilesTabControl" Grid.Row="1" Margin="0,10,0,10"/>

        <!-- Кнопка объединения файлов -->
        <StackPanel Grid.Row="2" Orientation="Horizontal">
            <Button Content="Объединить файлы" Width="150" Height="30" Click="CombineFiles_Click"/>
            <Button Content="Редактировать и Экспортировать" Width="200" Height="30" Margin="10,0,0,0" Click="EditAndExport_Click" IsEnabled="False" x:Name="EditExportButton"/>
        </StackPanel>
    </Grid>
</Window>



<Window x:Class="TxtProcessorApp.EditWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TxtProcessorApp"
        Title="Редактирование данных" Height="600" Width="900">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- DataGrid для отображения и редактирования данных -->
        <DataGrid x:Name="EditDataGrid" Grid.Row="0" AutoGenerateColumns="True" 
                  CanUserAddRows="True" CanUserDeleteRows="True" 
                  IsReadOnly="False" 
                  SelectionUnit="CellOrRowHeader" 
                  SelectedCellsChanged="EditDataGrid_SelectedCellsChanged">
            <!-- Контекстное меню для вставки строк и столбцов -->
            <DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Вставить строку выше" Click="InsertRowAbove_Click"/>
                    <MenuItem Header="Вставить строку ниже" Click="InsertRowBelow_Click"/>
                    <Separator/>
                    <MenuItem Header="Вставить столбец слева" Click="InsertColumnLeft_Click"/>
                    <MenuItem Header="Вставить столбец справа" Click="InsertColumnRight_Click"/>
                </ContextMenu>
            </DataGrid.ContextMenu>
        </DataGrid>

        <!-- Панель кнопок ниже DataGrid -->
        <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,10,0,0">
            <!-- Элемент управления для выбора разделителя -->
            <ComboBox x:Name="DelimiterComboBox" Width="100" Height="30" SelectedIndex="0">
                <ComboBoxItem Content="Пробел"/>
                <ComboBoxItem Content="Табуляция"/>
                <ComboBoxItem Content="Запятая"/>
            </ComboBox>
            <Button Content="Экспортировать файл" Width="150" Height="30" Margin="10,0,0,0" Click="ExportButton_Click"/>
        </StackPanel>
    </Grid>
</Window>



<Window x:Class="TxtProcessorApp.InputDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Ввод" Height="150" Width="400" WindowStartupLocation="CenterOwner" ResizeMode="NoResize">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <TextBlock x:Name="PromptTextBlock" Grid.Row="0" Text="Prompt:" Margin="0,0,0,10" TextWrapping="Wrap"/>

        <TextBox x:Name="ResponseTextBox" Grid.Row="1" Height="25"/>

        <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
            <Button Content="OK" Width="75" Margin="0,0,10,0" IsDefault="True" Click="OK_Click"/>
            <Button Content="Отмена" Width="75" IsCancel="True"/>
        </StackPanel>
    </Grid>
</Window>



using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace TxtProcessorApp
{
    public partial class MainWindow : Window
    {
        // Словарь для хранения данных из файлов. Ключ - имя файла, значение - список строк данных.
        private Dictionary<string, List<string[]>> fileData = new Dictionary<string, List<string[]>>();

        // Хранение объединённых данных для дальнейшего редактирования
        private DataTable combinedDataTable = null;

        public MainWindow()
        {
            InitializeComponent();
        }

        // Обработчик кнопки загрузки файлов
        private void LoadFiles_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog
            {
                Multiselect = true,
                Filter = "Text files (*.txt)|*.txt"
            };

            if (ofd.ShowDialog() == true)
            {
                foreach (var file in ofd.FileNames)
                {
                    ProcessFile(file);
                }

                // Обновляем TabControl с вкладками для каждого файла
                PopulateTabControl();

                // Деактивируем кнопку редактирования до объединения
                EditExportButton.IsEnabled = false;
                combinedDataTable = null;
            }
        }

        // Метод для обработки отдельного файла
        private void ProcessFile(string filePath)
        {
            List<string[]> processedLines = new List<string[]>();

            try
            {
                var lines = File.ReadAllLines(filePath).Skip(11); // Пропуск первых 11 строк

                foreach (var line in lines)
                {
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    var columns = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                    if (columns.Length == 0)
                        continue;

                    // Проверка первого столбца
                    if (columns[0].ToLower() == "nan" || string.IsNullOrWhiteSpace(columns[0]))
                        continue;

                    // Создаем список для новых столбцов
                    List<string> newColumns = new List<string>();

                    // Добавляем столбцы, кроме первого
                    for (int i = 1; i < columns.Length; i++)
                    {
                        newColumns.Add(columns[i]);
                    }

                    processedLines.Add(newColumns.ToArray());
                }

                // Добавляем обработанные данные в словарь
                string fileName = System.IO.Path.GetFileName(filePath);

                // Проверяем, если файл уже загружен, добавляем суффикс
                string originalFileName = fileName;
                int duplicateCount = 1;
                while (fileData.ContainsKey(fileName))
                {
                    fileName = $"{System.IO.Path.GetFileNameWithoutExtension(originalFileName)}_{duplicateCount}{System.IO.Path.GetExtension(originalFileName)}";
                    duplicateCount++;
                }

                fileData[fileName] = processedLines;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Ошибка при обработке файла {filePath}:\n{ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // Метод для заполнения TabControl вкладками для каждого файла
        private void PopulateTabControl()
        {
            FilesTabControl.Items.Clear();

            foreach (var kvp in fileData)
            {
                string fileName = kvp.Key;
                List<string[]> data = kvp.Value;

                // Создаем DataGrid для текущего файла
                DataGrid dataGrid = new DataGrid
                {
                    AutoGenerateColumns = true,
                    IsReadOnly = true
                };

                // Преобразуем данные в DataTable
                DataTable dataTable = ConvertToDataTable(data);
                dataGrid.ItemsSource = dataTable.DefaultView;

                // Создаем вкладку
                TabItem tabItem = new TabItem
                {
                    Header = fileName,
                    Content = dataGrid
                };

                FilesTabControl.Items.Add(tabItem);
            }
        }

        // Метод для преобразования списка строк в DataTable с нужными названиями столбцов
        private DataTable ConvertToDataTable(List<string[]> data)
        {
            DataTable dt = new DataTable();

            if (data == null || data.Count == 0)
                return dt;

            // Создание столбцов с заданными названиями
            dt.Columns.Add("№");
            dt.Columns.Add("BASE-1");
            dt.Columns.Add("Noise");
            dt.Columns.Add("Time");
            dt.Columns.Add("Time UTC");

            // Добавление строк
            foreach (var row in data)
            {
                DataRow dr = dt.NewRow();
                dr["№"] = row[0];
                dr["BASE-1"] = row.Length > 1 ? row[1] : string.Empty;
                dr["Noise"] = row.Length > 2 ? row[2] : string.Empty;
                dr["Time"] = row.Length > 3 ? row[3] : string.Empty;
                dr["Time UTC"] = row.Length > 4 ? row[4] : string.Empty;
                dt.Rows.Add(dr);
            }

            return dt;
        }

        // Обработчик кнопки объединения файлов
        private void CombineFiles_Click(object sender, RoutedEventArgs e)
        {
            if (!fileData.Any())
            {
                MessageBox.Show("Нет загруженных файлов для объединения.", "Информация", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            List<string[]> combinedData = new List<string[]>();
            int lineNumber = 1;

            foreach (var file in fileData.Values)
            {
                foreach (var row in file)
                {
                    if (row.Length < 3)
                        continue; // Убедитесь, что есть минимум 3 столбца

                    // Извлечение необходимых столбцов
                    string secondColumn = row[1];
                    string thirdColumn = row[2];
                    string fourthColumn = row.Length >= 4 ? row[3] : "0"; // Если нет 4-го столбца, используем "0"

                    // Обработка пятого столбца
                    if (double.TryParse(fourthColumn, NumberStyles.Any, CultureInfo.InvariantCulture, out double number))
                    {
                        double divided = number / 24;
                        TimeSpan time = TimeSpan.FromDays(divided);
                        string timeString = time.ToString(@"hh\:mm\:ss");
                        combinedData.Add(new string[]
                        {
                            lineNumber.ToString(),
                            secondColumn,
                            thirdColumn,
                            fourthColumn,
                            timeString
                        });
                    }
                    else
                    {
                        combinedData.Add(new string[]
                        {
                            lineNumber.ToString(),
                            secondColumn,
                            thirdColumn,
                            fourthColumn,
                            "InvalidNumber"
                        });
                    }

                    lineNumber++;
                }
            }

            // Преобразуем объединённые данные в DataTable с нужными названиями столбцов
            combinedDataTable = ConvertToCombinedDataTable(combinedData);

            // Активируем кнопку редактирования
            EditExportButton.IsEnabled = true;

            MessageBox.Show("Файлы успешно объединены. Теперь вы можете отредактировать данные и экспортировать.", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        // Метод для преобразования объединённых данных в DataTable с нужными названиями столбцов
        private DataTable ConvertToCombinedDataTable(List<string[]> data)
        {
            DataTable dt = new DataTable();

            if (data == null || data.Count == 0)
                return dt;

            // Создание столбцов согласно требованиям
            dt.Columns.Add("№");
            dt.Columns.Add("BASE-1");
            dt.Columns.Add("Noise");
            dt.Columns.Add("Time");
            dt.Columns.Add("Time UTC");

            // Добавление строк
            foreach (var row in data)
            {
                DataRow dr = dt.NewRow();
                dr["№"] = row[0];
                dr["BASE-1"] = row.Length > 1 ? row[1] : string.Empty;
                dr["Noise"] = row.Length > 2 ? row[2] : string.Empty;
                dr["Time"] = row.Length > 3 ? row[3] : string.Empty;
                dr["Time UTC"] = row.Length > 4 ? row[4] : string.Empty;
                dt.Rows.Add(dr);
            }

            return dt;
        }

        // Обработчик кнопки Редактировать и Экспортировать
        private void EditAndExport_Click(object sender, RoutedEventArgs e)
        {
            if (combinedDataTable == null)
            {
                MessageBox.Show("Нет объединённых данных для редактирования.", "Информация", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            // Создаём и открываем окно редактирования
            EditWindow editWindow = new EditWindow(combinedDataTable);
            editWindow.Owner = this;
            editWindow.ShowDialog();

            // После закрытия EditWindow обновляем данные в TabControl (опционально)
            // Можно перезагрузить TabControl, чтобы отобразить отредактированные данные
            // В данном примере это не делается, но можно реализовать по желанию
        }
    }
}


using Microsoft.Win32;
using System;
using System.Data;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace TxtProcessorApp
{
    /// <summary>
    /// Логика взаимодействия для EditWindow.xaml
    /// </summary>
    public partial class EditWindow : Window
    {
        private DataTable _dataTable;

        public EditWindow(DataTable dataTable)
        {
            InitializeComponent();
            _dataTable = dataTable;
            EditDataGrid.ItemsSource = _dataTable.DefaultView;

            // Разрешаем добавление и удаление строк через интерфейс DataGrid
            EditDataGrid.CanUserAddRows = true;
            EditDataGrid.CanUserDeleteRows = true;
        }

        #region Вставка строк и столбцов

        // Вставка строки выше выбранной
        private void InsertRowAbove_Click(object sender, RoutedEventArgs e)
        {
            int rowIndex = GetSelectedRowIndex();
            if (rowIndex != -1)
            {
                _dataTable.Rows.InsertAt(_dataTable.NewRow(), rowIndex);
            }
            else
            {
                // Если ничего не выбрано, вставляем в конец
                _dataTable.Rows.Add(_dataTable.NewRow());
            }

            RefreshDataGrid();
        }

        // Вставка строки ниже выбранной
        private void InsertRowBelow_Click(object sender, RoutedEventArgs e)
        {
            int rowIndex = GetSelectedRowIndex();
            if (rowIndex != -1)
            {
                _dataTable.Rows.InsertAt(_dataTable.NewRow(), rowIndex + 1);
            }
            else
            {
                // Если ничего не выбрано, вставляем в конец
                _dataTable.Rows.Add(_dataTable.NewRow());
            }

            RefreshDataGrid();
        }

        // Вставка столбца слева от выбранного
        private void InsertColumnLeft_Click(object sender, RoutedEventArgs e)
        {
            int columnIndex = GetSelectedColumnIndex();
            InsertNewColumn(columnIndex, "NewColumn");
            RefreshDataGrid();
        }

        // Вставка столбца справа от выбранного
        private void InsertColumnRight_Click(object sender, RoutedEventArgs e)
        {
            int columnIndex = GetSelectedColumnIndex();
            InsertNewColumn(columnIndex + 1, "NewColumn");
            RefreshDataGrid();
        }

        // Добавление нового столбца в указанное место
        private void InsertNewColumn(int index, string defaultName)
        {
            // Предлагаем пользователю ввести имя нового столбца
            InputDialog inputDialog = new InputDialog("Введите имя нового столбца:", defaultName);
            if (inputDialog.ShowDialog() == true)
            {
                string columnName = inputDialog.ResponseText.Trim();
                if (string.IsNullOrEmpty(columnName))
                {
                    MessageBox.Show("Имя столбца не может быть пустым.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                // Проверяем, нет ли уже столбца с таким именем
                if (_dataTable.Columns.Contains(columnName))
                {
                    MessageBox.Show("Столбец с таким именем уже существует.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }

                // Создаём новый столбец
                DataColumn newColumn = new DataColumn(columnName, typeof(string));

                // Вставляем столбец в нужное место
                _dataTable.Columns.Add(newColumn);
                newColumn.SetOrdinal(Math.Min(index, _dataTable.Columns.Count - 1));

                // Устанавливаем значение по умолчанию для существующих строк
                foreach (DataRow row in _dataTable.Rows)
                {
                    row[newColumn] = string.Empty;
                }
            }
            else
            {
                // Если пользователь отменил ввод, автоматически генерируем уникальное имя
                string autoColumnName = GenerateUniqueColumnName("NewColumn");
                DataColumn newColumn = new DataColumn(autoColumnName, typeof(string));
                _dataTable.Columns.Add(newColumn);
                newColumn.SetOrdinal(Math.Min(index, _dataTable.Columns.Count - 1));

                foreach (DataRow row in _dataTable.Rows)
                {
                    row[newColumn] = string.Empty;
                }
            }
        }

        // Генерация уникального имени столбца
        private string GenerateUniqueColumnName(string baseName)
        {
            int suffix = 1;
            string newName = baseName;
            while (_dataTable.Columns.Contains(newName))
            {
                newName = $"{baseName}_{suffix}";
                suffix++;
            }
            return newName;
        }

        // Получение индекса выбранной строки
        private int GetSelectedRowIndex()
        {
            if (EditDataGrid.SelectedItem is DataRowView selectedRow)
            {
                return _dataTable.Rows.IndexOf(selectedRow.Row);
            }
            return -1;
        }

        // Получение индекса выбранного столбца
        private int GetSelectedColumnIndex()
        {
            if (EditDataGrid.SelectedCells.Count > 0)
            {
                var selectedCell = EditDataGrid.SelectedCells[0];
                var column = selectedCell.Column;
                if (column != null)
                {
                    return column.DisplayIndex;
                }
            }
            return -1;
        }

        #endregion

        // Метод для обновления привязки данных к DataGrid
        private void RefreshDataGrid()
        {
            // Получаем текущий view
            var view = CollectionViewSource.GetDefaultView(EditDataGrid.ItemsSource);

            if (view != null)
            {
                view.Refresh();
            }
        }

        // Обработчик изменения выбранных ячеек (опционально)
        private void EditDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            // Дополнительная логика при изменении выбора (если требуется)
        }

        // Обработчик кнопки Экспорта файла
        private void ExportButton_Click(object sender, RoutedEventArgs e)
        {
            // Выбор разделителя (табуляция)
            string delimiter = "\t";

            SaveFileDialog sfd = new SaveFileDialog
            {
                Filter = "Text files (*.txt)|*.txt",
                FileName = "EditedCombinedFile.txt"
            };

            if (sfd.ShowDialog() == true)
            {
                try
                {
                    using (StreamWriter sw = new StreamWriter(sfd.FileName, false, Encoding.UTF8))
                    {
                        // Запись заголовков столбцов
                        string[] headers = _dataTable.Columns
                            .Cast<DataColumn>()
                            .Select(column => column.ColumnName)
                            .ToArray();
                        sw.WriteLine(string.Join(delimiter, headers));

                        // Запись данных строк
                        foreach (DataRow row in _dataTable.Rows)
                        {
                            string[] fields = new string[_dataTable.Columns.Count];
                            for (int i = 0; i < _dataTable.Columns.Count; i++)
                            {
                                string field = row[i].ToString();
                                // Если поле содержит разделитель, обрамляем его в кавычки
                                if (field.Contains(delimiter))
                                {
                                    field = $"\"{field}\"";
                                }
                                fields[i] = field;
                            }
                            sw.WriteLine(string.Join(delimiter, fields));
                        }
                    }

                    MessageBox.Show($"Файл успешно экспортирован по адресу:\n{sfd.FileName}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Ошибка при сохранении файла:\n{ex.Message}", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
    }
}



using System.Windows;

namespace TxtProcessorApp
{
    /// <summary>
    /// Логика взаимодействия для InputDialog.xaml
    /// </summary>
    public partial class InputDialog : Window
    {
        public string ResponseText { get; private set; }

        public InputDialog(string question, string defaultAnswer = "")
        {
            InitializeComponent();
            PromptTextBlock.Text = question;
            ResponseTextBox.Text = defaultAnswer;
            ResponseTextBox.SelectAll();
            ResponseTextBox.Focus();
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            ResponseText = ResponseTextBox.Text;
            DialogResult = true;
        }
    }
}