1
0
Fork 0

refactor(P5b-7): 잔여 이벤트 핸들러 전부 커맨드/behavior로 — XAML 이벤트 핸들러 0개

Microsoft.Xaml.Behaviors.Wpf 도입. MainWindow.xaml에 직접 이벤트 핸들러(Click/SelectionChanged/Drop/
MouseUp 등) 0개 — 전부 선언적 바인딩·커맨드·InvokeCommandAction으로 전환.

- 드래그앤드롭(DragOver/DragLeave/Drop) → i:EventTrigger + InvokeCommandAction(PassEventArgsToCommand),
  HandleDragOver/HandleFilesDropped(DragEventArgs) 추출.
- 동적 포맷 콤보 SelectionChanged → OutputFormatChangedCommand(OnOutputFormatSelected).
- 큐·이력 행 PreviewMouseLeftButtonUp → QueueRow/PastRowCommand(MouseButtonEventArgs, IsInsideButton 가드
  보존 + e.OriginalSource.DataContext로 항목 해소).
- ProcessQueueButton Click → ProcessQueueCommand.
- 검증: 빌드 0/0, 83 테스트 그린, publish 후 메인 창 크래시 없이 로드(behaviors self-contained 정상).
  드래그앤드롭·행 미리보기·포맷 변경 실동작은 GUI 스모크 권장(비치명적 실패 모드).
This commit is contained in:
Yun Chan 2026-06-02 10:17:21 +09:00
parent ccba168f9a
commit 944187c314
4 changed files with 58 additions and 25 deletions

View file

@ -2,6 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Title="FormatShift Utility"
Icon="pack://application:,,,/Assets/app-icon.png"
Width="1280" Height="960"
@ -11,9 +12,6 @@
WindowCornerPreference="Round"
WindowStartupLocation="CenterScreen"
AllowDrop="True"
Drop="OnFilesDropped"
DragOver="OnDragOver"
DragLeave="OnDragLeave"
TextOptions.TextFormattingMode="Display"
UseLayoutRounding="True">
<Window.Resources>
@ -31,6 +29,18 @@
<KeyBinding Key="F5" Command="{Binding RefreshCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
</Window.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DragOver">
<i:InvokeCommandAction Command="{Binding DragOverCommand, RelativeSource={RelativeSource AncestorType=Window}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="DragLeave">
<i:InvokeCommandAction Command="{Binding DragLeaveCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Drop">
<i:InvokeCommandAction Command="{Binding DropCommand, RelativeSource={RelativeSource AncestorType=Window}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid Background="{StaticResource FsBgBase}">
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
@ -97,8 +107,13 @@
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ComboBox x:Name="OutputFormatCombo" Grid.Column="1"
Margin="8,0,0,0" VerticalAlignment="Center"
SelectionChanged="OnOutputFormatChanged"/>
Margin="8,0,0,0" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding OutputFormatChangedCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</Grid>
<TextBlock x:Name="OutputFormatHint" Margin="0,6,0,0"
Style="{StaticResource FsCaptionStyle}"
@ -315,7 +330,7 @@
Content="Idle — drop files to begin"
Style="{StaticResource FsPrimaryButtonStyle}"
IsEnabled="False"
Click="OnProcessQueueClick"/>
Command="{Binding ProcessQueueCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
</StackPanel>
</Border>
</Grid>
@ -456,9 +471,12 @@
Background="{StaticResource FsBgPanel}"
BorderBrush="{StaticResource FsBorderSubtle}"
BorderThickness="1"
Cursor="Hand"
PreviewMouseLeftButtonUp="OnQueueRowClick"
Tag="{Binding}">
Cursor="Hand">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding QueueRowCommand, RelativeSource={RelativeSource AncestorType=Window}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2"/>
@ -570,9 +588,12 @@
<Border BorderBrush="#0DFFFFFF"
BorderThickness="0,0,0,1" Padding="0,12"
Cursor="Hand"
Background="Transparent"
PreviewMouseLeftButtonUp="OnPastRowClick"
Tag="{Binding}">
Background="Transparent">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding PastRowCommand, RelativeSource={RelativeSource AncestorType=Window}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>