1
0
Fork 0

refactor(P5b-5): 버튼 Click 핸들러 10개 → 커맨드 바인딩

상호작용 핸들러 중 '커맨드화 가능한' 순수 버튼 클릭을 전부 RelayCommand + Command 바인딩으로 전환.

- 상단바 5개(Settings/Register/Diagnose/ExportLog/ClearAll) + 폴더선택/취소/미리보기열기
  + 항목제거(CommandParameter={Binding}) + 폴더열기(CommandParameter={Binding RevealPath}).
- OnRemoveQueueItem→RemoveQueueItem(QueueItem?), OnOpenFolderClick→OpenFolderForPath(string?) 추출
  (sender.Tag 의존 제거 → CommandParameter).
- 검증: 빌드 0/0, 83 테스트 그린, publish 후 메인 창 크래시 없이 로드(언핸들드 로그 없음).
- 잔여 핸들러는 MVVM에서도 뷰/behavior 영역: 드래그앤드롭, SelectionChanged/ValueChanged,
  미리보기 마우스클릭, 탭·충돌 ToggleButton 그룹(IsChecked 상호배제), 복합 상태 ProcessQueue 버튼.
This commit is contained in:
Yun Chan 2026-06-02 10:06:25 +09:00
parent fa385178b2
commit a05bbcf709
2 changed files with 51 additions and 32 deletions

View file

@ -39,6 +39,18 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
public ICommand CloseCommand { get; }
public ICommand RefreshCommand { get; }
// 상단바·액션 버튼 커맨드 (P5b: Click 핸들러 → 커맨드 바인딩)
public ICommand SettingsCommand { get; }
public ICommand RegisterCommand { get; }
public ICommand DiagnoseCommand { get; }
public ICommand ExportLogCommand { get; }
public ICommand ClearAllCommand { get; }
public ICommand PickOutputFolderCommand { get; }
public ICommand CancelProcessingCommand { get; }
public ICommand PreviewOpenFolderCommand { get; }
public ICommand RemoveQueueItemCommand { get; }
public ICommand OpenFolderCommand { get; }
public MainWindow(ConversionEngine engine, ISettingsStore settings, IReadOnlyList<string>? initialFiles = null)
{
_engine = engine;
@ -50,6 +62,17 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
CloseCommand = new RelayCommand(_ => Close());
RefreshCommand = new RelayCommand(_ => ApplyAppDataStats());
SettingsCommand = new RelayCommand(_ => OnSettingsClick(this, new RoutedEventArgs()));
RegisterCommand = new RelayCommand(_ => OnRegisterClick(this, new RoutedEventArgs()));
DiagnoseCommand = new RelayCommand(_ => OnDiagnoseClick(this, new RoutedEventArgs()));
ExportLogCommand = new RelayCommand(_ => OnExportLogClick(this, new RoutedEventArgs()));
ClearAllCommand = new RelayCommand(_ => OnClearAllClick(this, new RoutedEventArgs()));
PickOutputFolderCommand = new RelayCommand(_ => OnPickOutputFolderClick(this, new RoutedEventArgs()));
CancelProcessingCommand = new RelayCommand(_ => OnCancelProcessingClick(this, new RoutedEventArgs()));
PreviewOpenFolderCommand = new RelayCommand(_ => OnPreviewOpenFolder(this, new RoutedEventArgs()));
RemoveQueueItemCommand = new RelayCommand(p => RemoveQueueItem(p as QueueItem));
OpenFolderCommand = new RelayCommand(p => OpenFolderForPath(p as string));
InitializeComponent();
// ActiveQueueList/PastResultsList의 ItemsSource는 XAML이 ActiveQueue/PastResults에 바인딩(선언적).
@ -201,16 +224,14 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
}
}
private void OnRemoveQueueItem(object sender, RoutedEventArgs e)
private void RemoveQueueItem(QueueItem? item)
{
if (sender is FrameworkElement fe && fe.Tag is QueueItem item)
{
_activeQueue.Remove(item);
UpdateBadges();
UpdateProcessQueueButton();
UpdateActiveQueueVisibility();
RefreshAvailableOutputFormats();
}
if (item is null) return;
_activeQueue.Remove(item);
UpdateBadges();
UpdateProcessQueueButton();
UpdateActiveQueueVisibility();
RefreshAvailableOutputFormats();
}
private void UpdateActiveQueueVisibility()
@ -811,21 +832,19 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
ApplyAppDataStats();
}
private void OnOpenFolderClick(object sender, RoutedEventArgs e)
private static void OpenFolderForPath(string? path)
{
if (sender is FrameworkElement fe && fe.Tag is string path && File.Exists(path))
if (string.IsNullOrEmpty(path) || !File.Exists(path)) return;
try
{
try
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = "explorer.exe",
Arguments = $"/select,\"{path}\"",
UseShellExecute = true,
});
}
catch { }
FileName = "explorer.exe",
Arguments = $"/select,\"{path}\"",
UseShellExecute = true,
});
}
catch { }
}
public static string HumanizeBytes(long bytes)