// MainPage.xaml.cs using System.Collections.ObjectModel; using Microsoft.Maui.Controls; namespace MauiApp1; public partial class MainPage : ContentPage { private readonly IFileSystemService _fileService; public ObservableCollection LeftItems { get; set; } = new(); public ObservableCollection RightItems { get; set; } = new(); public string LeftPath { get; set; } = string.Empty; public string RightPath { get; set; } = string.Empty; private string _currentLeftPath; private string _currentRightPath; private FileSystemItem? _selectedLeftItem; private FileSystemItem? _selectedRightItem; public MainPage(IFileSystemService fileService) { InitializeComponent(); _fileService = fileService; BindingContext = this; var root = _fileService.GetRootPath(); LoadDirectory(root, true); LoadDirectory(root, false); } private void LoadDirectory(string path, bool isLeft) { var items = _fileService.GetDirectoryContents(path).ToList(); if (isLeft) { LeftItems.Clear(); foreach (var item in items) LeftItems.Add(item); _currentLeftPath = path; LeftPath = path; } else { RightItems.Clear(); foreach (var item in items) RightItems.Add(item); _currentRightPath = path; RightPath = path; } } private void OnLeftSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection.FirstOrDefault() is FileSystemItem item) { // Сохраняем выбор _selectedLeftItem = item; // Если это ".." или папка — переходим if (item.Name == ".." || item.IsDirectory) { LoadDirectory(item.FullName, true); // После перехода — сбрасываем выбор, чтобы не осталось выделения в новой папке _selectedLeftItem = null; LeftPanel.SelectedItem = null; } // Если это файл — ничего не делаем, оставляем его выделенным } } private void OnRightSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection.FirstOrDefault() is FileSystemItem item) { _selectedRightItem = item; if (item.Name == ".." || item.IsDirectory) { LoadDirectory(item.FullName, false); _selectedRightItem = null; RightPanel.SelectedItem = null; } } } private async void OnCopyClicked(object sender, EventArgs e) { await ProcessFileOperation(async (src, destDir) => { if (Directory.Exists(src)) await CopyDirectory(src, Path.Combine(destDir, Path.GetFileName(src))); else File.Copy(src, Path.Combine(destDir, Path.GetFileName(src)), overwrite: true); }, "Copy"); } private async void OnMoveClicked(object sender, EventArgs e) { await ProcessFileOperation((src, destDir) => { var dest = Path.Combine(destDir, Path.GetFileName(src)); if (Directory.Exists(src)) Directory.Move(src, dest); else File.Move(src, dest, overwrite: true); return Task.CompletedTask; }, "Move"); } private async void OnDeleteClicked(object sender, EventArgs e) { var item = _selectedLeftItem ?? _selectedRightItem; if (item == null) return; var confirm = await DisplayAlert("Delete", $"Delete '{item.Name}'?", "Yes", "No"); if (confirm) { if (item.IsDirectory) Directory.Delete(item.FullName, recursive: true); else File.Delete(item.FullName); // Обновляем обе панели (или только ту, откуда удалили) LoadDirectory(_currentLeftPath, true); LoadDirectory(_currentRightPath, false); } } private async void OnMkdirClicked(object sender, EventArgs e) { var result = await DisplayPromptAsync("New Folder", "Folder name:", "Create", "Cancel"); if (string.IsNullOrWhiteSpace(result)) return; // Создаём в активной панели (выберем левую, если выделение слева, иначе правую) string targetPath = (_selectedLeftItem != null || LeftItems.Count > 0) ? _currentLeftPath : _currentRightPath; string newPath = Path.Combine(targetPath, result.Trim()); if (!Directory.Exists(newPath)) { Directory.CreateDirectory(newPath); LoadDirectory(_currentLeftPath, true); LoadDirectory(_currentRightPath, false); } else { await DisplayAlert("Error", "Folder already exists.", "OK"); } } private void OnExitClicked(object sender, EventArgs e) { Application.Current?.Quit(); } private async Task CopyDirectory(string sourceDir, string targetDir) { Directory.CreateDirectory(targetDir); foreach (var file in Directory.GetFiles(sourceDir)) { await Task.Run(() => File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)), overwrite: true)); } foreach (var dir in Directory.GetDirectories(sourceDir)) { await CopyDirectory(dir, Path.Combine(targetDir, Path.GetFileName(dir))); } } private async Task ProcessFileOperation(Func operation, string actionName) { var srcItem = _selectedLeftItem ?? _selectedRightItem; if (srcItem == null) { await DisplayAlert("Error", "Select a file or folder first.", "OK"); return; } // Определяем целевую директорию: противоположная панель string destDir = (srcItem == _selectedLeftItem) ? _currentRightPath : _currentLeftPath; try { await operation(srcItem.FullName, destDir); // Обновляем обе панели LoadDirectory(_currentLeftPath, true); LoadDirectory(_currentRightPath, false); } catch (Exception ex) { await DisplayAlert("Error", $"{actionName} failed: {ex.Message}", "OK"); } } }