сделай в окне столбцы No1 No2 как №1 №2, но при экспорте в файл должны записаться просто №

<Window x:Class="TxtProcessorApp.MagneteWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TxtProcessorApp"
        Title=".magnete Файлы" Height="700" Width="1000">
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <!-- Центр для TabControl -->
            <RowDefinition Height="Auto"/>
            <!-- Нижняя панель с кнопками -->
        </Grid.RowDefinitions>

        <!-- TabControl для отображения .magnete файлов -->
        <TabControl x:Name="MagneteTabControl" Grid.Row="0" Margin="0,0,0,10">
            <!-- Вкладки будут добавляться динамически -->
        </TabControl>

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

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;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
using NetTopologySuite.Geometries;

namespace TxtProcessorApp
{
    public partial class MagneteWindow : Window
    {
        private Dictionary<string, List<string[]>> magneteFileData;
        private DataTable combinedMagneteDataTable = null;

        public MagneteWindow(Dictionary<string, List<string[]>> loadedMagneteData)
        {
            InitializeComponent();
            magneteFileData = loadedMagneteData;
            PopulateMagneteTabControl();
        }

        private void PopulateMagneteTabControl()
        {
            MagneteTabControl.Items.Clear();

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

                DataGrid dataGrid = CreateDataGrid(data);

                TabItem tabItem = new TabItem
                {
                    Header = fileName,
                    Content = dataGrid
                };

                MagneteTabControl.Items.Add(tabItem);
            }
        }

        private DataGrid CreateDataGrid(List<string[]> data)
        {
            DataGrid dataGrid = new DataGrid
            {
                AutoGenerateColumns = true,
                IsReadOnly = true,
                CanUserAddRows = false,
                CanUserDeleteRows = false,
                Margin = new Thickness(0, 0, 0, 0)
            };

            // Добавление стилей для ячеек и заголовков столбцов
            Style cellStyle = new Style(typeof(DataGridCell));
            cellStyle.Setters.Add(new Setter(DataGridCell.PaddingProperty, new Thickness(5)));
            cellStyle.Setters.Add(new Setter(DataGridCell.HorizontalContentAlignmentProperty, HorizontalAlignment.Center));

            Style headerStyle = new Style(typeof(DataGridColumnHeader));
            headerStyle.Setters.Add(new Setter(DataGridColumnHeader.HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
            headerStyle.Setters.Add(new Setter(DataGridColumnHeader.FontWeightProperty, FontWeights.Bold));

            dataGrid.CellStyle = cellStyle;
            dataGrid.ColumnHeaderStyle = headerStyle;

            DataTable dataTable = ConvertToDataTable(data);
            dataGrid.ItemsSource = dataTable.DefaultView;

            return dataGrid;
        }

        private DataTable ConvertToDataTable(List<string[]> data)
        {
            DataTable dt = new DataTable();

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

            // Определение столбцов только для исходных данных .magnete файлов
            dt.Columns.Add("Stan", typeof(string));
            dt.Columns.Add("Zeit", typeof(string));
            dt.Columns.Add("Noise", typeof(string));
            dt.Columns.Add("Time", typeof(string));
            dt.Columns.Add("TimeUTC", typeof(string));

            foreach (var row in data)
            {
                DataRow dr = dt.NewRow();
                dr["Stan"] = row.Length > 0 ? row[0].Trim() : string.Empty;
                dr["Zeit"] = row.Length > 1 ? row[1].Trim() : string.Empty;
                dr["Noise"] = row.Length > 2 ? row[2].Trim() : string.Empty;
                dr["Time"] = row.Length > 3 ? row[3].Trim() : string.Empty;
                dr["TimeUTC"] = row.Length > 4 ? row[4].Trim() : string.Empty;
                dt.Rows.Add(dr);
            }

            return dt;
        }

        // Метод логирования расчётов и ошибок
        private void LogCalculation(string message, string logFileName = "calculation_log.txt")
        {
            string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, logFileName);
            try
            {
                File.AppendAllText(logFilePath, $"{DateTime.Now}: {message}{Environment.NewLine}");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Не удалось записать лог: {ex.Message}", "Ошибка логирования", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        // Метод для определения UTM-зоны по долготе
        private int GetUTMZone(double longitude)
        {
            // Убедитесь, что долгота находится в диапазоне от -180 до 180 градусов
            if (longitude < -180 || longitude > 180)
                throw new ArgumentOutOfRangeException("Долгота должна быть в диапазоне от -180 до 180 градусов.");

            // Формула для расчёта зоны
            int zone = (int)Math.Floor((longitude + 180) / 6) + 1;
            return zone;
        }

        // Метод для преобразования WGS84 координат в UTM
        private (double Easting, double Northing) ConvertWGS84ToUTM(double longitude, double latitude, int utmZone)
        {
            // Определяем систему координат WGS84
            var wgs84 = GeographicCoordinateSystem.WGS84;

            // Определяем систему координат UTM для данного пояса и полушария
            var utmCS = ProjectedCoordinateSystem.WGS84_UTM(utmZone, latitude >= 0);

            // Создаём трансформацию
            var transformFactory = new CoordinateTransformationFactory();
            var transformation = transformFactory.CreateFromCoordinateSystems(wgs84, utmCS);

            // Преобразование координат
            double[] fromPoint = new double[] { longitude, latitude };
            double[] toPoint = transformation.MathTransform.Transform(fromPoint);

            return (toPoint[0], toPoint[1]); // Easting, Northing
        }

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

            // Фиксированная дата (06.01.1980) в UTC
            DateTime fixedDate = new DateTime(1980, 1, 6, 0, 0, 0, DateTimeKind.Utc);

            // Объединяем все данные из .magnete файлов
            combinedMagneteDataTable = new DataTable();

            // Определение столбцов с уникальными внутренними именами
            combinedMagneteDataTable.Columns.Add("DATA", typeof(string));
            combinedMagneteDataTable.Columns.Add("DATA_UTC", typeof(string));
            combinedMagneteDataTable.Columns.Add("TIME", typeof(string));
            combinedMagneteDataTable.Columns.Add("TIME_UTC", typeof(string));
            combinedMagneteDataTable.Columns.Add("Долгота_WGS", typeof(string)); // раньше "Noise"
            combinedMagneteDataTable.Columns.Add("Широта_WGS", typeof(string));  // раньше "Zeit"
            combinedMagneteDataTable.Columns.Add("Долгота_UTM", typeof(double)); // раньше "Zero1"
            combinedMagneteDataTable.Columns.Add("Широта_UTM", typeof(double));  // раньше "Zero2"
            combinedMagneteDataTable.Columns.Add("No1", typeof(int));             // раньше "SequentialNumber1"
            combinedMagneteDataTable.Columns.Add("Альтитуда", typeof(string));    // раньше "Time"
            combinedMagneteDataTable.Columns.Add("No2", typeof(int));             // раньше "SequentialNumber2"
            combinedMagneteDataTable.Columns.Add("Shark", typeof(string));        // раньше "TimeUTC"

            int sequentialNumber = 1;
            List<string> errorMessages = new List<string>();

            foreach (var file in magneteFileData.Values)
            {
                foreach (var row in file)
                {
                    // Создание новой строки для объединённой таблицы
                    DataRow newRow = combinedMagneteDataTable.NewRow();

                    // Столбцы "DATA UTC"
                    newRow["DATA_UTC"] = fixedDate.ToString("dd.MM.yyyy");

                    // Столбцы "TIME" и "TIME UTC"
                    string stanValue = row.Length > 0 ? row[0].Trim() : string.Empty;
                    newRow["TIME"] = stanValue;

                    // Столбцы "Долгота WGS" и "Широта WGS"
                    string zeitValue = row.Length > 1 ? row[1].Trim() : string.Empty;
                    newRow["Широта_WGS"] = zeitValue;

                    string noiseValue = row.Length > 2 ? row[2].Trim() : string.Empty;
                    newRow["Долгота_WGS"] = noiseValue;

                    // Столбцы "No1" и "No2"
                    newRow["No1"] = sequentialNumber; // SequentialNumber1
                    newRow["No2"] = sequentialNumber; // SequentialNumber2

                    // Столбцы "Альтитуда" и "Shark"
                    string timeValueStr = row.Length > 3 ? row[3].Trim() : string.Empty;
                    newRow["Альтитуда"] = timeValueStr;

                    string timeUtcValue = row.Length > 4 ? row[4].Trim() : string.Empty;
                    newRow["Shark"] = timeUtcValue;

                    // Столбцы "Долгота UTM" и "Широта UTM" будут заполнены позже
                    newRow["Долгота_UTM"] = 0.0; // Изначально 0.0, потом заменим
                    newRow["Широта_UTM"] = 0.0;

                    // Для логирования
                    string computedDateStr = "N/A";
                    string computedTimeStr = "N/A"; // Объявлено

                    // Преобразование координат из "Долгота WGS" и "Широта WGS" в UTM
                    double longitude, latitude;
                    bool validCoordinates = true;

                    if (!double.TryParse(noiseValue, NumberStyles.Any, CultureInfo.InvariantCulture, out longitude))
                    {
                        string error = $"Не удалось распарсить Долгота WGS='{noiseValue}' как долготу в строке: {string.Join("\t", row)}.";
                        errorMessages.Add(error);
                        LogCalculation(error);
                        validCoordinates = false;
                    }

                    if (!double.TryParse(zeitValue, NumberStyles.Any, CultureInfo.InvariantCulture, out latitude))
                    {
                        string error = $"Не удалось распарсить Широта WGS='{zeitValue}' как широту в строке: {string.Join("\t", row)}.";
                        errorMessages.Add(error);
                        LogCalculation(error);
                        validCoordinates = false;
                    }

                    if (validCoordinates)
                    {
                        try
                        {
                            // Определяем UTM-зону
                            int utmZone = GetUTMZone(longitude);

                            // Преобразуем координаты в UTM
                            var utmCoordinates = ConvertWGS84ToUTM(longitude, latitude, utmZone);

                            // Записываем UTM координаты в "Долгота UTM" и "Широта UTM"
                            newRow["Долгота_UTM"] = utmCoordinates.Easting;
                            newRow["Широта_UTM"] = utmCoordinates.Northing;
                        }
                        catch (Exception ex)
                        {
                            string error = $"Ошибка при преобразовании координат (Долгота WGS='{noiseValue}', Широта WGS='{zeitValue}') в строке: {string.Join("\t", row)}. Текст ошибки: {ex.Message}.";
                            errorMessages.Add(error);
                            LogCalculation(error);
                        }
                    }

                    // Обработка столбца "Stan" как секунд с фиксированной даты
                    if (double.TryParse(stanValue, NumberStyles.Any, CultureInfo.InvariantCulture, out double stanSeconds))
                    {
                        if (stanSeconds < 0)
                        {
                            string warning = $"Отрицательное значение TIME='{stanSeconds}' в строке: {string.Join("\t", row)}. Установка даты как фиксированной.";
                            errorMessages.Add(warning);
                            LogCalculation(warning);

                            newRow["DATA"] = fixedDate.ToString("dd.MM.yyyy");
                            // ComputedTime - фиксированное время минус 18 секунд (оставляет статус 00:00:00.0)
                            computedTimeStr = fixedDate.ToString("HH:mm:ss.f");
                            newRow["TIME_UTC"] = computedTimeStr;
                        }
                        else
                        {
                            try
                            {
                                // Добавляем секунды к фиксированной дате
                                DateTime computedDate = fixedDate.AddSeconds(stanSeconds);

                                // Проверка, что дата находится в допустимом диапазоне
                                if (computedDate > DateTime.MaxValue || computedDate < DateTime.MinValue)
                                {
                                    string warning = $"TIME слишком велико='{stanSeconds}' в строке: {string.Join("\t", row)}. Установка даты как фиксированной.";
                                    errorMessages.Add(warning);
                                    LogCalculation(warning);

                                    newRow["DATA"] = fixedDate.ToString("dd.MM.yyyy");
                                    computedTimeStr = fixedDate.ToString("HH:mm:ss.f");
                                    newRow["TIME_UTC"] = computedTimeStr;
                                }
                                else
                                {
                                    newRow["DATA"] = computedDate.ToString("dd.MM.yyyy");

                                    // Формат даты
                                    computedDateStr = computedDate.ToString("dd.MM.yyyy");

                                    // Вычисляем ComputedTime как остаток времени после вычитания 18 секунд
                                    TimeSpan timeOfDay = computedDate.TimeOfDay;

                                    // Вычитаем 18 секунд
                                    TimeSpan offsetTime = TimeSpan.FromSeconds(18);
                                    TimeSpan computedTime;

                                    if (timeOfDay >= offsetTime)
                                    {
                                        computedTime = timeOfDay - offsetTime;
                                    }
                                    else
                                    {
                                        // Если время дня меньше 18 секунд, устанавливаем время как 00:00:00.0
                                        computedTime = TimeSpan.Zero;
                                        string info = $"Время дня меньше 18 секунд в строке: {string.Join("\t", row)}. ComputedTime установлено как 00:00:00.0.";
                                        errorMessages.Add(info);
                                        LogCalculation(info);
                                    }

                                    // Округляем каждый TimeSpan.TotalSeconds до одного знака после запятой
                                    double totalSeconds = computedTime.TotalSeconds;
                                    double roundedSeconds = Math.Round(totalSeconds, 1, MidpointRounding.AwayFromZero);

                                    // Создаём TimeSpan из округлённого количества секунд
                                    TimeSpan roundedTime = TimeSpan.FromSeconds(roundedSeconds);

                                    // Форматируем ComputedTime с учетом одной десятичной части секунд
                                    computedTimeStr = roundedTime.ToString(@"hh\:mm\:ss\.f");
                                    newRow["TIME_UTC"] = computedTimeStr;
                                }
                            }
                            catch (Exception ex)
                            {
                                string error = $"Ошибка при расчёте даты для TIME='{stanSeconds}' в строке: {string.Join("\t", row)}. Текст ошибки: {ex.Message}. Установка даты как фиксированной.";
                                errorMessages.Add(error);
                                LogCalculation(error);

                                newRow["DATA"] = fixedDate.ToString("dd.MM.yyyy");
                                computedDateStr = fixedDate.ToString("dd.MM.yyyy");
                                computedTimeStr = fixedDate.ToString("HH:mm:ss.f");
                                newRow["TIME_UTC"] = computedTimeStr;
                            }
                        }
                    }
                    else
                    {
                        // Если парсинг не удался, устанавливаем фиксированную дату и время, и логируем
                        string error = $"Не удалось распарсить TIME='{stanValue}' в строке: {string.Join("\t", row)}. Установка даты как фиксированной.";
                        errorMessages.Add(error);
                        LogCalculation(error);

                        newRow["DATA"] = fixedDate.ToString("dd.MM.yyyy");
                        computedDateStr = fixedDate.ToString("dd.MM.yyyy");
                        computedTimeStr = fixedDate.ToString("HH:mm:ss.f");
                        newRow["TIME_UTC"] = computedTimeStr;
                    }

                    combinedMagneteDataTable.Rows.Add(newRow);
                    sequentialNumber++;

                    // Логируем расчёты для каждой строки
                    string logMessage = $"TIME: '{stanValue}', ComputedDate: {computedDateStr}, ComputedTime: {computedTimeStr}";
                    LogCalculation(logMessage);
                }
            }

            // Создаём DataGrid с явно определёнными столбцами
            DataGrid dataGridCombined = new DataGrid
            {
                AutoGenerateColumns = false,
                IsReadOnly = true,
                CanUserAddRows = false,
                CanUserDeleteRows = false,
            };

            // Определяем столбцы вручную с необходимым форматированием
            // 1. DATA
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "DATA",
                Binding = new Binding("DATA"),
                Width = new DataGridLength(150, DataGridLengthUnitType.Auto)
            });

            // 2. DATA UTC
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "DATA UTC",
                Binding = new Binding("DATA_UTC"),
                Width = new DataGridLength(150, DataGridLengthUnitType.Auto)
            });

            // 3. TIME
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "TIME",
                Binding = new Binding("TIME"),
                Width = new DataGridLength(100, DataGridLengthUnitType.Auto)
            });

            // 4. TIME UTC
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "TIME UTC",
                Binding = new Binding("TIME_UTC"),
                Width = new DataGridLength(150, DataGridLengthUnitType.Auto)
            });

            // 5. Долгота WGS
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Долгота WGS",
                Binding = new Binding("Долгота_WGS"),
                Width = new DataGridLength(120, DataGridLengthUnitType.Auto)
            });

            // 6. Широта WGS
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Широта WGS",
                Binding = new Binding("Широта_WGS"),
                Width = new DataGridLength(120, DataGridLengthUnitType.Auto)
            });

            // 7. Долгота UTM
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Долгота UTM",
                Binding = new Binding("Долгота_UTM") { StringFormat = "F2" }, // Форматирование до 2 десятичных знаков
                Width = new DataGridLength(140, DataGridLengthUnitType.Auto)
            });

            // 8. Широта UTM
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Широта UTM",
                Binding = new Binding("Широта_UTM") { StringFormat = "F2" },
                Width = new DataGridLength(140, DataGridLengthUnitType.Auto)
            });

            // 9. №1
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "№",
                Binding = new Binding("No1"),
                Width = new DataGridLength(60, DataGridLengthUnitType.Auto)
            });

            // 10. Альтитуда
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Альтитуда",
                Binding = new Binding("Альтитуда"),
                Width = new DataGridLength(100, DataGridLengthUnitType.Auto)
            });

            // 11. №2
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "№",
                Binding = new Binding("No2"),
                Width = new DataGridLength(60, DataGridLengthUnitType.Auto)
            });

            // 12. Shark
            dataGridCombined.Columns.Add(new DataGridTextColumn
            {
                Header = "Shark",
                Binding = new Binding("Shark"),
                Width = new DataGridLength(100, DataGridLengthUnitType.Auto)
            });

            // Присваиваем DataTable как источник данных
            dataGridCombined.ItemsSource = combinedMagneteDataTable.DefaultView;

            // Добавляем вкладку с объединёнными данными
            TabItem tabItemCombined = new TabItem
            {
                Header = "Объединённые данные",
                Content = dataGridCombined
            };

            MagneteTabControl.Items.Add(tabItemCombined);

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

            // Логируем основные события
            LogCalculation($"Файлы .magnete успешно объединены. Объединено строк: {combinedMagneteDataTable.Rows.Count}.");

            if (errorMessages.Any())
            {
                string allErrors = string.Join("\n", errorMessages);
                LogCalculation($"Обнаружены следующие проблемы:\n{allErrors}");
                MessageBox.Show($"Файлы .magnete объединены с ошибками. Подробности в файле логов.", "Внимание", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
            else
            {
                MessageBox.Show($"Файлы .magnete успешно объединены. Объединено строк: {combinedMagneteDataTable.Rows.Count}", "Успех", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        private void EditAndExportMagnete_Click(object sender, RoutedEventArgs e)
        {
            if (combinedMagneteDataTable == null)
            {
                MessageBox.Show("Нет объединённых данных для редактирования.", "Информация", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

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

<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>

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 = "EditedCombinedMagneteFile.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);
                }
            }
        }
    }
}