Files
SheetMe/src/SheetMe.Designer/Views/QueryEditorWindow.xaml
T
MsystechandClaude Opus 5 308197c15e 별도 창 전수 점검 — 암시 Window 스타일이 파생 클래스에 적용된 적이 없었다
사용자 지적: "다른 창으로(새창으로 열리는) 실행하는 항목들도 모두 점검해줘".

[근본 원인 — 대화상자 전체가 다크에서 흰 창이었다]
WPF 는 암시 스타일을 요소의 **정확한 런타임 타입**으로만 찾는다. 저장소의 모든 창이
Window 를 상속한 클래스(SheetOpenDialogView : Window, QueryEditorWindow : Window …)라
DesignerTheme.xaml 의 <Style TargetType="Window"> 는 **단 한 번도 적용된 적이 없다**.
결과: 창 배경이 WPF 기본 흰색으로 남고, 그 위 글자는 암시 TextBlock 스타일(B.Ink #EDEDED)을
정상적으로 받는다 → **다크 테마에서 흰 바탕에 흰 글자**. 쿼리 편집기의 변수 목록처럼 라벨이
통째로 사라지는 화면이 나왔다.

라이트에서 눈에 덜 띈 이유는 우연이다 — 기본 흰색(#FFFFFF)이 의도값 B.AppBg(#F5F5F5)와
거의 같아서다. 그래서 지금까지 라이트만 보고는 발견되지 않았다.

수정: 스타일에 x:Key="ThemedWindow" 를 주고 창 10종에 직접 걸었다(코드로 짓는
ColorPickerWindow 는 생성자에서 TryFindResource). 순수 Window 인스턴스용 암시 스타일은
BasedOn 으로 남겼다. 앞으로 창을 추가할 때 잊지 않도록 스타일 위에 경고 주석을 붙였다.

[신규 진단 --dialog-shots <출력폴더>]
이 결함은 정적 분석으로는 못 잡았다(앞선 감사에서 "대화상자들은 암시 Window 스타일을 그대로
받는다"고 잘못 결론냈다). 실입력 주입은 화면 잠금·세션 격리 상태에서 OS 가 거부한다
(SetCursorPos 무시, SendKeys "Access is denied" — 이번에도 중간부터 막혔다).
그래서 창을 화면 밖(-10000)에 띄워 RenderTargetBitmap 으로 찍는 진단을 만들었다.
창 8종 × 2테마 = 16장을 한 번에 남기고, 각 창의 **해석된 Background 와 Style 적용 여부를
텍스트로 함께 보고**한다 — 픽셀만 보면 원인을 못 가린다(실제로 이 한 줄이 원인을 확정했다).
표본 데이터는 실제 사용 시와 같은 형태로 넣었다(빈 껍데기를 찍으면 의미가 없다).

함정 2개를 코드에 남겼다.
· 기본 ShutdownMode 가 OnLastWindowClose 라 찍고 닫는 순간 앱이 종료된다 → OnExplicitShutdown.
· Window.Content 만 렌더하면 창 배경이 빠져 투명(=PNG 검정)이 되고, 다크처럼 보이는 착시로
  라이트 결함이 가려진다 → 배경을 먼저 칠하고 그 위에 콘텐츠를 그린다.

[함께 고친 것 — 여러 줄 입력이 세로 가운데 정렬]
쿼리 편집기의 SQL 이 큰 상자 한가운데 떠 있었다. 템플릿 트리거가 ScrollViewer 의
VerticalContentAlignment 만 Stretch 로 바꿨는데, 텍스트를 배치하는 건 TextBox 자신의
VerticalContentAlignment 이라 아무 효과가 없었다. Style.Triggers 로 옮겨 Top 으로 두고
여러 줄일 때 Padding 도 넉넉히 준다. 인스펙터의 여러 줄 속성 행에도 함께 적용된다.

검증: 창 8종 × 2테마 전부 재렌더해 배경 확인(다크 #0E0E0E / 라이트 #F5F5F5,
미리보기만 의도대로 B.CanvasBg). 테스트 124/124, edit-smoke 실패 0,
**종이 렌더 P062 픽셀 대조 차이 0**.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 12:54:55 +09:00

66 lines
4.0 KiB
XML

<Window x:Class="SheetMe.Designer.Views.QueryEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="쿼리 편집" Width="960" Height="560" MinWidth="720" MinHeight="400"
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
Style="{StaticResource ThemedWindow}">
<DockPanel Margin="12">
<TextBlock x:Name="HintText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}" TextWrapping="Wrap" Margin="0,0,0,8"
Text="작성 시점에 &lt;&lt;변수&gt;&gt; 가 실제 값으로 치환됩니다. 변수는 클래스 전체 이름을 포함해야 하므로 우측 목록을 더블클릭해 삽입하세요 — 임의로 줄여 쓰면 치환되지 않고 SQL 에 그대로 남아 오류가 납니다."/>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<TextBlock x:Name="LengthText" VerticalAlignment="Center" Margin="0,0,12,0" Foreground="{DynamicResource B.Muted}"/>
<Button Content="확인" Padding="20,5" Click="OnConfirm"/>
<Button Content="취소" Padding="20,5" Margin="8,0,0,0" IsCancel="True"/>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition x:Name="SplitterColumn" Width="8"/>
<ColumnDefinition x:Name="VariableColumn" Width="330"/>
</Grid.ColumnDefinitions>
<!-- SQL 편집 영역 -->
<TextBox x:Name="SqlBox" Grid.Column="0"
FontFamily="Consolas, D2Coding, 굴림체" FontSize="13"
AcceptsReturn="True" AcceptsTab="True"
TextWrapping="NoWrap"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
TextChanged="OnSqlChanged"/>
<!-- 공용 ColSplitter 스타일을 쓴다 — Background 만 주면 양 테마에서 배경과 1.1~1.3:1 로 붙어 손잡이가 안 보인다 -->
<GridSplitter Grid.Column="1" Style="{StaticResource ColSplitter}"/>
<!-- 치환 변수 목록 (SQL 용도에서만 표시) -->
<DockPanel x:Name="VariablePane" Grid.Column="2">
<TextBlock DockPanel.Dock="Top" Text="치환 변수 (더블클릭 삽입)" FontWeight="Bold"
Foreground="{DynamicResource B.Muted}" Margin="4,0,0,6"/>
<ListBox x:Name="VariableList" FontSize="11" MouseDoubleClick="OnInsertVariable"
FontFamily="Consolas, D2Coding, 굴림체"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,1" ToolTip="{Binding Token}">
<TextBlock Text="{Binding Description}" FontFamily="Segoe UI, 맑은 고딕" FontSize="12"/>
<TextBlock Text="{Binding Token}" Foreground="{DynamicResource B.Muted}" FontSize="10"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" FontWeight="Bold" Margin="2,8,0,3"
FontFamily="Segoe UI, 맑은 고딕" FontSize="12"
Foreground="{DynamicResource B.AccentText}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
</DockPanel>
</Grid>
</DockPanel>
</Window>