별도 창 전수 점검 — 암시 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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ff87353d0d
commit
308197c15e
@@ -171,6 +171,11 @@ public partial class App : Application
|
|||||||
return Diagnostics.DbSmoke.RunTableSearch(args[1], args[2]);
|
return Diagnostics.DbSmoke.RunTableSearch(args[1], args[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.Length >= 2 && args[0] == "--dialog-shots")
|
||||||
|
{
|
||||||
|
return Diagnostics.DialogShots.Run(args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
MessageBox.Show($"알 수 없는 진단 옵션입니다: {args[0]}", "서식생성기",
|
MessageBox.Show($"알 수 없는 진단 옵션입니다: {args[0]}", "서식생성기",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using SheetMe.Core.Models;
|
||||||
|
using SheetMe.Data.Stores;
|
||||||
|
using SheetMe.Designer.Services;
|
||||||
|
using SheetMe.Designer.ViewModels;
|
||||||
|
|
||||||
|
namespace SheetMe.Designer.Diagnostics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 별도 창(대화상자) 오프스크린 스냅샷 — <c>--dialog-shots <출력폴더></c>.
|
||||||
|
///
|
||||||
|
/// 창 10종을 다크·라이트 양 테마로 열어 PNG 로 남긴다. 목적은 하나다:
|
||||||
|
/// <b>테마 대비 결함을 사람 손 없이 재현 가능하게 확인한다.</b>
|
||||||
|
/// 실입력(마우스·키보드) 주입은 화면 잠금·세션 격리 상태에서 OS 가 거부하지만
|
||||||
|
/// 이 경로는 창을 화면 밖에 띄워 RenderTargetBitmap 으로 찍으므로 그 제약을 받지 않는다.
|
||||||
|
///
|
||||||
|
/// 창은 화면 밖(-10000)에 <c>Show()</c> 로 띄운다 — 레이아웃이 실제로 돌아야 템플릿·트리거가
|
||||||
|
/// 적용된 상태로 찍힌다(Measure/Arrange 만으로는 Window 크롬이 구성되지 않는다).
|
||||||
|
/// 모든 창은 찍은 뒤 즉시 닫는다.
|
||||||
|
/// </summary>
|
||||||
|
public static class DialogShots
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
public static int Run(string outputDirectory)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(outputDirectory);
|
||||||
|
// 기본 ShutdownMode 는 OnLastWindowClose 라, 찍고 닫는 순간 마지막 창이 사라져 앱이 종료된다
|
||||||
|
// (그 뒤 Application.Current 가 null 이 되어 테마 교체에서 NRE). 명시 종료로 바꾼다.
|
||||||
|
Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
|
||||||
|
var lines = new List<string>();
|
||||||
|
|
||||||
|
foreach (var light in new[] { false, true })
|
||||||
|
{
|
||||||
|
ThemeManager.Apply(light);
|
||||||
|
var suffix = light ? "light" : "dark";
|
||||||
|
foreach (var (name, factory) in Factories())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var window = factory();
|
||||||
|
Capture(window, Path.Combine(outputDirectory, $"{name}-{suffix}.png"));
|
||||||
|
// 창 배경이 실제로 무엇으로 해석됐는지 함께 남긴다 — 픽셀만 보면 원인을 못 가린다.
|
||||||
|
// WPF 는 암시 스타일을 요소의 '정확한 타입'으로만 찾으므로, Window 를 상속한
|
||||||
|
// 대화상자에는 <Style TargetType="Window"> 가 적용되지 않는다(기본 흰 배경이 된다).
|
||||||
|
var background = window.Background is SolidColorBrush solid
|
||||||
|
? solid.Color.ToString()
|
||||||
|
: window.Background?.ToString() ?? "(null)";
|
||||||
|
var styled = window.Style is not null ? "스타일적용" : "스타일없음";
|
||||||
|
lines.Add($"OK {name}-{suffix} 배경={background} {styled}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
lines.Add($"FAIL {name}-{suffix} — {ex.GetType().Name}: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(Path.Combine(outputDirectory, "_report.txt"),
|
||||||
|
string.Join(Environment.NewLine, lines));
|
||||||
|
Console.WriteLine(string.Join(Environment.NewLine, lines));
|
||||||
|
return lines.Any(l => l.StartsWith("FAIL", StringComparison.Ordinal)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine($"대화상자 스냅샷 실패: {ex}");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>창 생성기 목록 — 실제 사용 시와 같은 인자로 만든다(빈 껍데기를 찍으면 의미가 없다)</summary>
|
||||||
|
private static List<(string Name, Func<Window> Factory)> Factories()
|
||||||
|
{
|
||||||
|
var designer = SampleDesigner();
|
||||||
|
return new List<(string, Func<Window>)>
|
||||||
|
{
|
||||||
|
("01-sheet-open", () => new Views.SheetOpenDialogView(_ => SampleSheets())),
|
||||||
|
("02-sheet-history", () => new Views.SheetHistoryDialogView("S999", "표본 서식", SampleVersions())),
|
||||||
|
("03-query-editor", () => new Views.QueryEditorWindow("데이터소스",
|
||||||
|
"SELECT ChtNum, PatNam FROM P_PatMst\nWHERE ChtNum = <<M.CMM.HISOperatingInfo.bzPatientInfo.ChtNum>>")),
|
||||||
|
("04-tag-picker", () => new Views.TagPickerDialogView("동작 태그", SampleTags(), SampleTags()[1])),
|
||||||
|
("05-mask-picker", () => new Views.MaskPickerDialogView("0000년 90월 90일")),
|
||||||
|
("06-font-manager", () => new Views.FontManagerDialogView(designer)),
|
||||||
|
("07-register-sheet", () => new Views.RegisterSheetDialogView("S999", "표본 서식")),
|
||||||
|
("08-preview", () => new Views.PreviewWindow(designer)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>화면 밖에 띄워 레이아웃을 돌린 뒤 PNG 로 찍고 닫는다</summary>
|
||||||
|
private static void Capture(Window window, string pngPath)
|
||||||
|
{
|
||||||
|
window.WindowStartupLocation = WindowStartupLocation.Manual;
|
||||||
|
window.Left = -10000;
|
||||||
|
window.Top = -10000;
|
||||||
|
window.ShowInTaskbar = false;
|
||||||
|
window.Show();
|
||||||
|
window.UpdateLayout();
|
||||||
|
// 레이아웃·비동기 로딩(Loaded 핸들러)이 한 바퀴 돌게 한다
|
||||||
|
Pump();
|
||||||
|
|
||||||
|
// 창 자체를 렌더한다 — Content 만 찍으면 Window.Background(B.AppBg)가 빠져 투명이 되고,
|
||||||
|
// PNG 에서 검정으로 저장돼 "다크처럼 보이는" 착시가 생긴다(라이트 결함이 가려진다).
|
||||||
|
var content = (FrameworkElement)window.Content;
|
||||||
|
var width = (int)Math.Ceiling(content.ActualWidth > 0 ? content.ActualWidth : window.Width);
|
||||||
|
var height = (int)Math.Ceiling(content.ActualHeight > 0 ? content.ActualHeight : window.Height);
|
||||||
|
var bitmap = new RenderTargetBitmap(Math.Max(1, width), Math.Max(1, height), 96, 96, PixelFormats.Pbgra32);
|
||||||
|
|
||||||
|
var drawing = new DrawingVisual();
|
||||||
|
using (var context = drawing.RenderOpen())
|
||||||
|
{
|
||||||
|
context.DrawRectangle(window.Background ?? Brushes.Transparent, null, new Rect(0, 0, width, height));
|
||||||
|
context.DrawRectangle(new VisualBrush(content) { Stretch = Stretch.None, AlignmentX = AlignmentX.Left, AlignmentY = AlignmentY.Top },
|
||||||
|
null, new Rect(0, 0, width, height));
|
||||||
|
}
|
||||||
|
bitmap.Render(drawing);
|
||||||
|
|
||||||
|
var encoder = new PngBitmapEncoder();
|
||||||
|
encoder.Frames.Add(BitmapFrame.Create(bitmap));
|
||||||
|
using (var stream = File.Create(pngPath))
|
||||||
|
{
|
||||||
|
encoder.Save(stream);
|
||||||
|
}
|
||||||
|
window.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>디스패처 큐를 비운다(Loaded/바인딩 갱신 반영)</summary>
|
||||||
|
private static void Pump()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(
|
||||||
|
() => { }, System.Windows.Threading.DispatcherPriority.ContextIdle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods - 표본 데이터
|
||||||
|
private static List<SheetSummary> SampleSheets() => new()
|
||||||
|
{
|
||||||
|
new SheetSummary("C020", "협진기록지", true, true, "A", "의사기록"),
|
||||||
|
new SheetSummary("C030", "Doctor's Order List", false, true, "A", "의사기록"),
|
||||||
|
new SheetSummary("P001", "간호 기록지", true, true, "E", "간호기록"),
|
||||||
|
new SheetSummary("F004", "임상생리신경검사", true, false, "D", "검사결과"),
|
||||||
|
new SheetSummary("Z001", "분류 없는 서식", false, true, string.Empty, "(미분류)"),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static List<DesignVersionInfo> SampleVersions() => new()
|
||||||
|
{
|
||||||
|
new DesignVersionInfo(52443, "202608121030", "011825", false),
|
||||||
|
new DesignVersionInfo(52380, "202607161422", "011825", true),
|
||||||
|
new DesignVersionInfo(52241, "202607160901", "MSYS", true),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string[] SampleTags() => new[]
|
||||||
|
{
|
||||||
|
"SetPatientName", "SetChartNumber", "EnableControl", "SetVisitDate", "ClearValue",
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>폰트 관리자·미리보기용 표본 문서 — 컨트롤이 있어야 목록이 비지 않는다</summary>
|
||||||
|
private static DesignerViewModel SampleDesigner()
|
||||||
|
{
|
||||||
|
var document = new FormDocument { FormId = "S999", Title = "표본 서식" };
|
||||||
|
var page = Core.Serialization.LegacyXmlSerializer.CreateEmptyPage(1);
|
||||||
|
page.Controls.Add(NewControl("Label", "Label1", "환자명", 40, 40, 120, 24));
|
||||||
|
page.Controls.Add(NewControl("TextBox", "TextBox1", string.Empty, 170, 40, 200, 26));
|
||||||
|
page.Controls.Add(NewControl("Label", "Label2", "생년월일", 40, 80, 120, 24));
|
||||||
|
document.Pages.Add(page);
|
||||||
|
return new DesignerViewModel(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ControlElement NewControl(string type, string id, string text, double x, double y, double w, double h)
|
||||||
|
{
|
||||||
|
var element = new ControlElement { Type = type, Id = id };
|
||||||
|
element.Bounds.X = x;
|
||||||
|
element.Bounds.Y = y;
|
||||||
|
element.Bounds.W = w;
|
||||||
|
element.Bounds.H = h;
|
||||||
|
if (text.Length > 0)
|
||||||
|
{
|
||||||
|
element.Props.SetText("Text", text);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -13,13 +13,26 @@
|
|||||||
<!-- ===== 창 공통(다이얼로그 배경/폰트 — 로컬 지정이 있으면 로컬 우선) =====
|
<!-- ===== 창 공통(다이얼로그 배경/폰트 — 로컬 지정이 있으면 로컬 우선) =====
|
||||||
FontSize/Foreground 가 없으면 대화상자들이 WPF 기본 12px + 시스템 검정으로 렌더돼
|
FontSize/Foreground 가 없으면 대화상자들이 WPF 기본 12px + 시스템 검정으로 렌더돼
|
||||||
메인 셸(13px)과 결이 어긋난다. 토큰 참조는 DynamicResource 로 둬야 테마 전환에 따라간다. -->
|
메인 셸(13px)과 결이 어긋난다. 토큰 참조는 DynamicResource 로 둬야 테마 전환에 따라간다. -->
|
||||||
<Style TargetType="Window">
|
<!--
|
||||||
|
⚠ 창에는 **반드시 Style="{StaticResource ThemedWindow}" 를 직접 걸어야 한다.**
|
||||||
|
WPF 는 암시 스타일을 요소의 '정확한 런타임 타입'으로만 찾는다. 모든 대화상자가
|
||||||
|
Window 를 **상속한** 클래스(SheetOpenDialogView : Window 등)라 아래 암시 스타일은
|
||||||
|
이들에게 단 한 번도 적용된 적이 없었다 — 진단(dialog-shots)이 창 8종 전부
|
||||||
|
배경=#FFFFFFFF / Style=null 로 보고했다. 결과적으로 다크 테마에서 흰 창 위에
|
||||||
|
B.Ink(#EDEDED) 글자가 얹혀 대화상자 내용이 통째로 보이지 않았다.
|
||||||
|
(TextBlock·TextBox 등은 정확한 타입이라 암시 스타일이 정상 적용돼, 창 배경만
|
||||||
|
WPF 기본 흰색으로 남는 형태로 드러났다.)
|
||||||
|
-->
|
||||||
|
<Style x:Key="ThemedWindow" TargetType="Window">
|
||||||
<Setter Property="Background" Value="{DynamicResource B.AppBg}" />
|
<Setter Property="Background" Value="{DynamicResource B.AppBg}" />
|
||||||
<Setter Property="FontFamily" Value="Malgun Gothic" />
|
<Setter Property="FontFamily" Value="Malgun Gothic" />
|
||||||
<Setter Property="FontSize" Value="13" />
|
<Setter Property="FontSize" Value="13" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
|
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<!-- 순수 Window 인스턴스용(파생 클래스에는 위 키 스타일을 직접 걸어야 한다) -->
|
||||||
|
<Style TargetType="Window" BasedOn="{StaticResource ThemedWindow}" />
|
||||||
|
|
||||||
<!-- ===== 타이포 ===== -->
|
<!-- ===== 타이포 ===== -->
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
|
<Setter Property="Foreground" Value="{DynamicResource B.Ink}" />
|
||||||
@@ -112,13 +125,22 @@
|
|||||||
<Trigger Property="IsKeyboardFocused" Value="True">
|
<Trigger Property="IsKeyboardFocused" Value="True">
|
||||||
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Accent}" />
|
<Setter TargetName="bd" Property="BorderBrush" Value="{DynamicResource B.Accent}" />
|
||||||
</Trigger>
|
</Trigger>
|
||||||
<Trigger Property="AcceptsReturn" Value="True">
|
|
||||||
<Setter TargetName="PART_ContentHost" Property="VerticalContentAlignment" Value="Stretch" />
|
|
||||||
</Trigger>
|
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
<Style.Triggers>
|
||||||
|
<!--
|
||||||
|
여러 줄 입력은 위에서부터 흘러야 한다. 종전에는 템플릿 트리거가 ScrollViewer 의
|
||||||
|
VerticalContentAlignment 만 Stretch 로 바꿨는데, 텍스트를 배치하는 것은 TextBox 자신의
|
||||||
|
VerticalContentAlignment 이라 아무 효과가 없었다 — 쿼리 편집기에서 SQL 이 큰 상자
|
||||||
|
한가운데 떠 있었다(dialog-shots 진단으로 확인).
|
||||||
|
-->
|
||||||
|
<Trigger Property="AcceptsReturn" Value="True">
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Top" />
|
||||||
|
<Setter Property="Padding" Value="6,5" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<!-- Framer 식 슬라이더(불투명도 등): 얇은 트랙 + 흰 원형 썸 -->
|
<!-- Framer 식 슬라이더(불투명도 등): 얇은 트랙 + 흰 원형 썸 -->
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ public sealed class ColorPickerWindow : Window
|
|||||||
private ColorPickerWindow(string? initialHex)
|
private ColorPickerWindow(string? initialHex)
|
||||||
{
|
{
|
||||||
Title = "색상 선택";
|
Title = "색상 선택";
|
||||||
|
// 암시 Window 스타일은 파생 클래스에 적용되지 않는다 — 직접 걸지 않으면 다크에서 흰 창이 된다
|
||||||
|
if (Application.Current?.TryFindResource("ThemedWindow") is Style themed)
|
||||||
|
{
|
||||||
|
Style = themed;
|
||||||
|
}
|
||||||
Width = 300;
|
Width = 300;
|
||||||
SizeToContent = SizeToContent.Height;
|
SizeToContent = SizeToContent.Height;
|
||||||
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="폰트 일괄 변경" Width="620" Height="560" MinWidth="520" MinHeight="420"
|
Title="폰트 일괄 변경" Width="620" Height="560" MinWidth="520" MinHeight="420"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<TextBlock DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}" TextWrapping="Wrap" Margin="0,0,0,8"
|
<TextBlock DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}" TextWrapping="Wrap" Margin="0,0,0,8"
|
||||||
Text="문서 전체의 (타입·글꼴·크기) 조합입니다. 변경할 조합을 선택(다중 가능)하고 새 글꼴을 지정하세요."/>
|
Text="문서 전체의 (타입·글꼴·크기) 조합입니다. 변경할 조합을 선택(다중 가능)하고 새 글꼴을 지정하세요."/>
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
Width="1440" Height="920" MinWidth="940" MinHeight="640"
|
Width="1440" Height="920" MinWidth="940" MinHeight="640"
|
||||||
WindowStyle="None" WindowStartupLocation="CenterScreen"
|
WindowStyle="None" WindowStartupLocation="CenterScreen"
|
||||||
Background="{DynamicResource B.AppBg}" FontFamily="Malgun Gothic" FontSize="13"
|
Background="{DynamicResource B.AppBg}" FontFamily="Malgun Gothic" FontSize="13"
|
||||||
Loaded="OnWindowLoaded" StateChanged="OnWindowStateChanged" Closing="OnWindowClosing">
|
Loaded="OnWindowLoaded" StateChanged="OnWindowStateChanged" Closing="OnWindowClosing"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
파일/앱 계열만 창 단위로 바인딩한다. 편집 계열(Ctrl+Z/C/V/X/D/A/G)은 CanvasKeyboardBehavior 가
|
파일/앱 계열만 창 단위로 바인딩한다. 편집 계열(Ctrl+Z/C/V/X/D/A/G)은 CanvasKeyboardBehavior 가
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="마스크 편집" Width="620" Height="620"
|
Title="마스크 편집" Width="620" Height="620"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<!--
|
<!--
|
||||||
백슬래시를 글리프로 보여주지 않는다 — 한글 글꼴에서 원화 기호(₩)로 렌더되어 오해를 부른다.
|
백슬래시를 글리프로 보여주지 않는다 — 한글 글꼴에서 원화 기호(₩)로 렌더되어 오해를 부른다.
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="미리보기" Width="900" Height="1000"
|
Title="미리보기" Width="900" Height="1000"
|
||||||
WindowStartupLocation="CenterOwner" Background="{DynamicResource B.CanvasBg}">
|
WindowStartupLocation="CenterOwner" Background="{DynamicResource B.CanvasBg}"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<ToolBarTray DockPanel.Dock="Top">
|
<ToolBarTray DockPanel.Dock="Top">
|
||||||
<ToolBar>
|
<ToolBar>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="쿼리 편집" Width="960" Height="560" MinWidth="720" MinHeight="400"
|
Title="쿼리 편집" Width="960" Height="560" MinWidth="720" MinHeight="400"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<TextBlock x:Name="HintText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}" TextWrapping="Wrap" Margin="0,0,0,8"
|
<TextBlock x:Name="HintText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}" TextWrapping="Wrap" Margin="0,0,0,8"
|
||||||
Text="작성 시점에 <<변수>> 가 실제 값으로 치환됩니다. 변수는 클래스 전체 이름을 포함해야 하므로 우측 목록을 더블클릭해 삽입하세요 — 임의로 줄여 쓰면 치환되지 않고 SQL 에 그대로 남아 오류가 납니다."/>
|
Text="작성 시점에 <<변수>> 가 실제 값으로 치환됩니다. 변수는 클래스 전체 이름을 포함해야 하므로 우측 목록을 더블클릭해 삽입하세요 — 임의로 줄여 쓰면 치환되지 않고 SQL 에 그대로 남아 오류가 납니다."/>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="상용구 관리" Width="560" Height="520" MinWidth="480" MinHeight="380"
|
Title="상용구 관리" Width="560" Height="520" MinWidth="480" MinHeight="380"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<TextBlock x:Name="HeaderText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
<TextBlock x:Name="HeaderText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
||||||
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="신규 서식 등록" Width="420" SizeToContent="Height"
|
Title="신규 서식 등록" Width="420" SizeToContent="Height"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False" ResizeMode="NoResize">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False" ResizeMode="NoResize"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<StackPanel Margin="16">
|
<StackPanel Margin="16">
|
||||||
<TextBlock Text="E_ShtMst 에 등록되지 않은 서식입니다. 신규 등록 후 저장합니다."
|
<TextBlock Text="E_ShtMst 에 등록되지 않은 서식입니다. 신규 등록 후 저장합니다."
|
||||||
TextWrapping="Wrap" Foreground="{DynamicResource B.Muted}" Margin="0,0,0,12"/>
|
TextWrapping="Wrap" Foreground="{DynamicResource B.Muted}" Margin="0,0,0,12"/>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="서식 수정이력" Width="560" Height="520" MinWidth="480" MinHeight="380"
|
Title="서식 수정이력" Width="560" Height="520" MinWidth="480" MinHeight="380"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<TextBlock x:Name="HeaderText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
<TextBlock x:Name="HeaderText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
||||||
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="DB에서 서식 열기" Width="680" Height="560"
|
Title="DB에서 서식 열기" Width="680" Height="560"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<DockPanel DockPanel.Dock="Top">
|
<DockPanel DockPanel.Dock="Top">
|
||||||
<Button DockPanel.Dock="Right" Content="검색" Padding="14,4" Margin="6,0,0,0" Click="OnSearch" IsDefault="True"/>
|
<Button DockPanel.Dock="Right" Content="검색" Padding="14,4" Margin="6,0,0,0" Click="OnSearch" IsDefault="True"/>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="태그 선택" Width="480" Height="560"
|
Title="태그 선택" Width="480" Height="560"
|
||||||
WindowStartupLocation="CenterOwner" ShowInTaskbar="False">
|
WindowStartupLocation="CenterOwner" ShowInTaskbar="False"
|
||||||
|
Style="{StaticResource ThemedWindow}">
|
||||||
<DockPanel Margin="12">
|
<DockPanel Margin="12">
|
||||||
<TextBlock x:Name="TitleText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
<TextBlock x:Name="TitleText" DockPanel.Dock="Top" Foreground="{DynamicResource B.Muted}"
|
||||||
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
TextWrapping="Wrap" Margin="0,0,0,8"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user