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:
parent
fa385178b2
commit
a05bbcf709
2 changed files with 51 additions and 32 deletions
|
|
@ -161,7 +161,7 @@
|
||||||
ToolTip="비워두면 원본 폴더 옆 서브폴더에 저장"/>
|
ToolTip="비워두면 원본 폴더 옆 서브폴더에 저장"/>
|
||||||
<Button Grid.Column="1" Margin="8,0,0,0" Width="36"
|
<Button Grid.Column="1" Margin="8,0,0,0" Width="36"
|
||||||
Content="…" Style="{StaticResource FsSecondaryButtonStyle}"
|
Content="…" Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnPickOutputFolderClick"/>
|
Command="{Binding PickOutputFolderCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<TextBlock x:Name="OutputDestHint" Margin="0,6,0,0"
|
<TextBlock x:Name="OutputDestHint" Margin="0,6,0,0"
|
||||||
Style="{StaticResource FsCaptionStyle}"
|
Style="{StaticResource FsCaptionStyle}"
|
||||||
|
|
@ -300,7 +300,7 @@
|
||||||
<Button x:Name="CancelProcessingButton" Grid.Column="1"
|
<Button x:Name="CancelProcessingButton" Grid.Column="1"
|
||||||
Content="취소" Padding="10,2"
|
Content="취소" Padding="10,2"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnCancelProcessingClick"/>
|
Command="{Binding CancelProcessingCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
@ -368,19 +368,19 @@
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||||
<Button Content="⚙ 설정" Margin="0,0,8,0"
|
<Button Content="⚙ 설정" Margin="0,0,8,0"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnSettingsClick"/>
|
Command="{Binding SettingsCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
<Button Content="Register Menu" Margin="0,0,8,0"
|
<Button Content="Register Menu" Margin="0,0,8,0"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnRegisterClick"/>
|
Command="{Binding RegisterCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
<Button Content="Diagnose" Margin="0,0,8,0"
|
<Button Content="Diagnose" Margin="0,0,8,0"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnDiagnoseClick"/>
|
Command="{Binding DiagnoseCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
<Button Content="Export Log" Margin="0,0,8,0"
|
<Button Content="Export Log" Margin="0,0,8,0"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnExportLogClick"/>
|
Command="{Binding ExportLogCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
<Button x:Name="ClearAllButton" Content="Clear All"
|
<Button x:Name="ClearAllButton" Content="Clear All"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnClearAllClick"/>
|
Command="{Binding ClearAllCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
@ -500,8 +500,8 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
ToolTip="큐에서 제거"
|
ToolTip="큐에서 제거"
|
||||||
Click="OnRemoveQueueItem"
|
Command="{Binding RemoveQueueItemCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
Tag="{Binding}">
|
CommandParameter="{Binding}">
|
||||||
<Path Width="13" Height="13" Stretch="Uniform"
|
<Path Width="13" Height="13" Stretch="Uniform"
|
||||||
Stroke="{StaticResource FsTextTertiary}"
|
Stroke="{StaticResource FsTextTertiary}"
|
||||||
StrokeThickness="2"
|
StrokeThickness="2"
|
||||||
|
|
@ -618,8 +618,8 @@
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
Padding="6"
|
Padding="6"
|
||||||
Click="OnOpenFolderClick"
|
Command="{Binding OpenFolderCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
Tag="{Binding RevealPath}"
|
CommandParameter="{Binding RevealPath}"
|
||||||
ToolTip="출력 파일이 있는 폴더 열기">
|
ToolTip="출력 파일이 있는 폴더 열기">
|
||||||
<Path Width="14" Height="14" Stretch="Uniform"
|
<Path Width="14" Height="14" Stretch="Uniform"
|
||||||
Stroke="{StaticResource FsTextTertiary}"
|
Stroke="{StaticResource FsTextTertiary}"
|
||||||
|
|
@ -779,7 +779,7 @@
|
||||||
|
|
||||||
<Button Content="Open in Explorer" Margin="0,16,0,0"
|
<Button Content="Open in Explorer" Margin="0,16,0,0"
|
||||||
Style="{StaticResource FsSecondaryButtonStyle}"
|
Style="{StaticResource FsSecondaryButtonStyle}"
|
||||||
Click="OnPreviewOpenFolder"
|
Command="{Binding PreviewOpenFolderCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
||||||
HorizontalAlignment="Stretch"/>
|
HorizontalAlignment="Stretch"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,18 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
public ICommand CloseCommand { get; }
|
public ICommand CloseCommand { get; }
|
||||||
public ICommand RefreshCommand { 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)
|
public MainWindow(ConversionEngine engine, ISettingsStore settings, IReadOnlyList<string>? initialFiles = null)
|
||||||
{
|
{
|
||||||
_engine = engine;
|
_engine = engine;
|
||||||
|
|
@ -50,6 +62,17 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
CloseCommand = new RelayCommand(_ => Close());
|
CloseCommand = new RelayCommand(_ => Close());
|
||||||
RefreshCommand = new RelayCommand(_ => ApplyAppDataStats());
|
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();
|
InitializeComponent();
|
||||||
|
|
||||||
// ActiveQueueList/PastResultsList의 ItemsSource는 XAML이 ActiveQueue/PastResults에 바인딩(선언적).
|
// ActiveQueueList/PastResultsList의 ItemsSource는 XAML이 ActiveQueue/PastResults에 바인딩(선언적).
|
||||||
|
|
@ -201,17 +224,15 @@ 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)
|
|
||||||
{
|
{
|
||||||
|
if (item is null) return;
|
||||||
_activeQueue.Remove(item);
|
_activeQueue.Remove(item);
|
||||||
UpdateBadges();
|
UpdateBadges();
|
||||||
UpdateProcessQueueButton();
|
UpdateProcessQueueButton();
|
||||||
UpdateActiveQueueVisibility();
|
UpdateActiveQueueVisibility();
|
||||||
RefreshAvailableOutputFormats();
|
RefreshAvailableOutputFormats();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateActiveQueueVisibility()
|
private void UpdateActiveQueueVisibility()
|
||||||
{
|
{
|
||||||
|
|
@ -811,10 +832,9 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
ApplyAppDataStats();
|
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
|
||||||
|
|
@ -826,7 +846,6 @@ public partial class MainWindow : Wpf.Ui.Controls.FluentWindow
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static string HumanizeBytes(long bytes)
|
public static string HumanizeBytes(long bytes)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue