diff --git a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs
index 3306400..cadc0f2 100644
--- a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs
+++ b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs
@@ -337,6 +337,20 @@ public static class EditSmoke
Check("미리보기: 컨테이너 안의 PrintOutPut=False 도 빠진다", afterHide < baseline,
$"요소 {baseline} → {afterHide} (안 줄면 최상위만 거르고 있다)");
+ // 보기 전환 — 레거시 미리보기는 PrintOutPut=False 를 그대로 보여 준다.
+ // 필터를 끄면 방금 뺀 것이 돌아와야 한다. 안 돌아오면 전환이 배선만 된 것이다.
+ int RenderedRaw()
+ {
+ var visual = (System.Windows.FrameworkElement)
+ Services.PrintService.BuildPageVisual(boxedVm.Pages[0], printFilter: false);
+ visual.Measure(new System.Windows.Size(720, 856));
+ visual.Arrange(new Rect(0, 0, 720, 856));
+ visual.UpdateLayout();
+ return CountVisuals(visual);
+ }
+ Check("미리보기: '화면 그대로' 로 바꾸면 숨긴 것이 돌아온다", RenderedRaw() > afterHide,
+ $"인쇄기준 {afterHide} → 화면기준 {RenderedRaw()}");
+
// 인쇄 필터가 캔버스로 새면 안 된다 — 편집 중인 것을 못 보면 고칠 수 없다
Check("미리보기: 캔버스는 자식을 그대로 다 보여 준다",
boxedPanel.Children.Count == 3, $"{boxedPanel.Children.Count} (기대 3)");
diff --git a/src/SheetMe.Designer/Services/PrintService.cs b/src/SheetMe.Designer/Services/PrintService.cs
index 30ae448..33f8460 100644
--- a/src/SheetMe.Designer/Services/PrintService.cs
+++ b/src/SheetMe.Designer/Services/PrintService.cs
@@ -49,8 +49,16 @@ public static class PrintService
return document;
}
- /// 페이지 컨트롤층 비주얼 — 크롬 없는 Canvas(그리기 순서 = 컬렉션 순서, 미리보기/인쇄 공용)
- public static UIElement BuildPageVisual(PageViewModel page)
+ ///
+ /// 페이지 컨트롤층 비주얼 — 크롬 없는 Canvas(그리기 순서 = 컬렉션 순서, 미리보기/인쇄 공용).
+ ///
+ /// 가 false 면 화면에 보이는 것을 그대로 그린다.
+ /// 레거시가 그렇게 동작한다 — 레거시 미리보기는 PrintOutPut=False 컨트롤을
+ /// 그대로 보여 주고(그 속성은 PrintMe 안에만 있다) 레거시 인쇄만 뺀다.
+ /// 두 눈이 필요해서 미리보기 창이 보기를 전환할 수 있게 열어 둔다.
+ /// 인쇄는 언제나 true 다 — 인쇄는 인쇄다.
+ ///
+ public static UIElement BuildPageVisual(PageViewModel page, bool printFilter = true)
{
var canvas = new Canvas
{
@@ -73,14 +81,16 @@ public static class PrintService
// ③ 을 오래 빠뜨려서 '인쇄 출력'을 꺼도 미리보기에 그대로 나왔다 —
// 저장 전 검증 수단이 거짓말을 하고 있었다.
// 캔버스는 계속 다 보여 준다(편집 중인 것을 못 보면 고칠 수 없다) — 여기만 거른다.
+ // Hidden(디자이너 임시 숨김)과 MDataTable(런타임 비가시)은 보기와 무관하게 항상 뺀다 —
+ // 레거시 미리보기에서도 안 보이는 것들이다. 보기가 가르는 것은 ③ 뿐이다.
if (control.Model.Hidden || control is DataTableViewModel
- || !SheetMe.Core.Catalog.PrintFilter.IsPrinted(control.Model))
+ || (printFilter && !SheetMe.Core.Catalog.PrintFilter.IsPrinted(control.Model)))
{
continue;
}
var presenter = new ContentPresenter
{
- Content = PrintProjection(control),
+ Content = PrintProjection(control, printFilter),
Width = Math.Max(1, control.Width),
Height = Math.Max(1, control.Height),
};
@@ -109,7 +119,7 @@ public static class PrintService
/// 자식 VM 은 새로 만들지 않고 원본을 그대로 담는다 — 해석된 글꼴·색이 유지된다.
/// 캔버스가 쓰는 VM 은 한 글자도 건드리지 않는다.
///
- private static object PrintProjection(ControlViewModel control)
+ private static object PrintProjection(ControlViewModel control, bool printFilter)
{
if (control is not ContainerViewModel container)
{
@@ -129,11 +139,11 @@ public static class PrintService
foreach (var child in container.Children)
{
if (child.Model.Hidden || child is DataTableViewModel
- || !SheetMe.Core.Catalog.PrintFilter.IsPrinted(child.Model))
+ || (printFilter && !SheetMe.Core.Catalog.PrintFilter.IsPrinted(child.Model)))
{
continue;
}
- if (PrintProjection(child) is ControlViewModel projected)
+ if (PrintProjection(child, printFilter) is ControlViewModel projected)
{
copy.Children.Add(projected);
}
diff --git a/src/SheetMe.Designer/Views/PreviewWindow.xaml b/src/SheetMe.Designer/Views/PreviewWindow.xaml
index d17d2c2..0a0d2c4 100644
--- a/src/SheetMe.Designer/Views/PreviewWindow.xaml
+++ b/src/SheetMe.Designer/Views/PreviewWindow.xaml
@@ -11,6 +11,16 @@
+
+
+
diff --git a/src/SheetMe.Designer/Views/PreviewWindow.xaml.cs b/src/SheetMe.Designer/Views/PreviewWindow.xaml.cs
index 54db252..c524f1c 100644
--- a/src/SheetMe.Designer/Views/PreviewWindow.xaml.cs
+++ b/src/SheetMe.Designer/Views/PreviewWindow.xaml.cs
@@ -121,6 +121,13 @@ public partial class PreviewWindow : Window
private void BuildPages()
{
+ // XAML 파싱 중에도 불린다 — 토글의 IsChecked="True" 가 파스 시점에 Checked 를 발생시키는데
+ // 그때 PagesHost 는 아직 만들어지지 않았다(토글이 트리에서 앞에 있다).
+ // 이 가드가 없으면 InitializeComponent 안에서 NullReferenceException 이 난다.
+ if (PagesHost is null)
+ {
+ return;
+ }
PagesHost.Children.Clear();
foreach (var page in designer.Pages)
{
@@ -130,7 +137,7 @@ public partial class PreviewWindow : Window
BorderBrush = System.Windows.Media.Brushes.LightGray,
BorderThickness = new Thickness(1),
Margin = new Thickness(0, 0, 0, 20),
- Child = PrintService.BuildPageVisual(page),
+ Child = PrintService.BuildPageVisual(page, PrintViewToggle.IsChecked == true),
Width = page.WidthDip,
Height = page.HeightDip,
};
@@ -143,6 +150,9 @@ public partial class PreviewWindow : Window
private void OnRefresh(object sender, RoutedEventArgs e) => BuildPages();
+ /// 보기 전환 — 인쇄 기준 / 화면 그대로
+ private void OnViewToggled(object sender, RoutedEventArgs e) => BuildPages();
+
private void OnPrint(object sender, RoutedEventArgs e)
{
try