초기 커밋: SheetMe 서식생성기 (P0~P5 완료 상태)
레거시 서식생성기(VB.NET WinForms) 대체용 C#/.NET 10 WPF 디자이너. 기준선: 실DB 활성 디자인 1,271건 왕복 의미론 diff 0 / 예외 0, 단위 테스트 49/49. 이 커밋에 함께 포함된 자격증명 분리: - appsettings.json 을 __HOST__/__PASSWORD__ 플레이스홀더로 전환 - 실접속 정보는 appsettings.Development.json 으로 분리(.gitignore 제외, csproj Debug 조건부 복사라 Release 산출물에 실리지 않음) - ConfigLoader 를 환경변수 > Development > appsettings 순 레이어링으로 변경, 미치환 플레이스홀더는 '미설정'으로 간주 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using SheetMe.Designer.ViewModels;
|
||||
using SheetMe.Designer.ViewModels.Controls;
|
||||
|
||||
namespace SheetMe.Designer.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 인쇄 서비스 — 페이지당 FixedPage 1:1(DIP)로 조립해 인쇄.
|
||||
/// 캔버스와 동일한 DataTemplate 사전(App 리소스)을 사용하므로 화면=인쇄 렌더가 일치한다.
|
||||
/// 용지 그림자 등 편집 크롬 없이 흰 배경 + 컨트롤만 그린다.
|
||||
/// </summary>
|
||||
public static class PrintService
|
||||
{
|
||||
#region Methods
|
||||
/// <summary>인쇄 대화상자 → 전체 페이지 인쇄</summary>
|
||||
public static void Print(DesignerViewModel designer, string documentName)
|
||||
{
|
||||
var dialog = new System.Windows.Controls.PrintDialog();
|
||||
if (dialog.ShowDialog() != true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var document = BuildFixedDocument(designer);
|
||||
dialog.PrintDocument(document.DocumentPaginator, $"SheetMe — {documentName}");
|
||||
}
|
||||
|
||||
/// <summary>페이지 VM 목록 → FixedDocument (미리보기/인쇄 공용)</summary>
|
||||
public static FixedDocument BuildFixedDocument(DesignerViewModel designer)
|
||||
{
|
||||
var document = new FixedDocument();
|
||||
foreach (var page in designer.Pages)
|
||||
{
|
||||
var fixedPage = new FixedPage
|
||||
{
|
||||
Width = page.WidthDip,
|
||||
Height = page.HeightDip,
|
||||
Background = page.PaperBrush,
|
||||
};
|
||||
fixedPage.Children.Add(BuildPageVisual(page));
|
||||
|
||||
var pageContent = new PageContent();
|
||||
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
|
||||
document.Pages.Add(pageContent);
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
/// <summary>페이지 컨트롤층 비주얼 — 크롬 없는 Canvas(그리기 순서 = 컬렉션 순서, 미리보기/인쇄 공용)</summary>
|
||||
public static UIElement BuildPageVisual(PageViewModel page)
|
||||
{
|
||||
var canvas = new Canvas
|
||||
{
|
||||
Width = page.WidthDip,
|
||||
Height = page.HeightDip,
|
||||
};
|
||||
TextOptions.SetTextFormattingMode(canvas, TextFormattingMode.Ideal);
|
||||
|
||||
// 종이 위 렌더는 레거시 충실 유지 — 앱 테마의 암시 TextBlock 스타일(다크 밝은 글자) 차단
|
||||
var paperText = new Style(typeof(TextBlock));
|
||||
paperText.Setters.Add(new Setter(TextBlock.ForegroundProperty, Brushes.Black));
|
||||
canvas.Resources.Add(typeof(TextBlock), paperText);
|
||||
|
||||
foreach (var control in page.Controls)
|
||||
{
|
||||
// 숨김 + 데이터소스(MDataTable — 런타임 비가시)는 인쇄/미리보기에서 제외
|
||||
if (control.Model.Hidden || control is DataTableViewModel)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var presenter = new ContentPresenter
|
||||
{
|
||||
Content = control,
|
||||
Width = Math.Max(1, control.Width),
|
||||
Height = Math.Max(1, control.Height),
|
||||
};
|
||||
Canvas.SetLeft(presenter, control.X);
|
||||
Canvas.SetTop(presenter, control.Y);
|
||||
canvas.Children.Add(presenter);
|
||||
}
|
||||
return canvas;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user