-
Notifications
You must be signed in to change notification settings - Fork 0
PageView
Page View: the presentation mode that lays the MarkdownRichEditor's Visual Document out on a Document Sheet of whole US Letter Pages floating on a scrolling canvas — the way a word processor shows a page — so every element, tables included, is confined to one page width instead of stretching to the pane, and the Sheet gains its next Page as soon as the content needs it. The Page is turned and inset by the one editor-wide Page Setup: its Page Orientation (8.5 × 11 portrait, 11 × 8.5 landscape) and its Print Margins — the same setup the Print Preview and the printout obey (INV-061). Page View is on by default; turned off, the editor fills the pane as a plain editing surface. It is presentation-only: turning it on or off never changes the Markdown Document or the result of a Capture (INV-058).
-
Class:
UI.Controls.PageView(astaticattached behaviour) -
Rule:
UI.Controls.DocumentSheet— the US Letter page'sWidth(816) andPageHeight(1056) at 96 dpi, and the whole-Page arithmetic (PageCount,HeightFor,TrailingSpaceFor), each parameterized by the page height the Page Setup's orientation yields -
Setup:
UI.Core.PageSetup— the orientation and margins the Sheet is laid out under (INV-061) - Sheet: DocumentSheetBackdrop — the paper and the Page Break rules, drawn behind the editor
-
Canvas colour:
EditorCanvasBrush(inPalette.Light.xaml/Palette.Dark.xaml)
Authored as an attached behaviour — the sanctioned home for view-interaction logic outside a ViewModel
— so the page-view concern lives here rather than swelling MarkdownRichEditor. The editor gets only a
tiny, page-agnostic seam: a RevealRectOverride the behaviour sets so find-match and heading jumps
scroll the canvas instead of the editor's own (now-disabled) scroll.
A RichTextBox does not virtualise — it lays its whole FlowDocument out at once — and a projected
GFM table is a WPF Table with no fixed width, so on an unbounded surface a table spans the entire
pane while prose wraps, and every widen (above all maximising) reflows the whole document. Page
View fixes this at the root: it lays the document out on a Sheet of one fixed width, so content width
no longer tracks the pane.
The behaviour is attached to the surface Grid that holds the Editor Gutter and the
editor, inside an outer ScrollViewer (the canvas). On enter it:
-
stops the editor scrolling itself (
VerticalScrollBarVisibility = Disabled) so it grows to its content's full height and the whole Sheet moves as one piece when the canvas scrolls; -
fixes the editor to the Sheet —
Widthat the Page Setup's oriented page width, its Print Margins as the pagePadding, a 1px edge — and its Grid column toAuto, so[gutter | Sheet]hugs its content. Changing theSetupwhile in Page View re-lays the Sheet out (INV-061); -
snaps the Sheet to whole Pages: the filler
DocumentSheet.TrailingSpaceForasks for — at the Page Setup's oriented page height — is added to the Sheet's bottom page margin, so a short document still shows a full Page and the Sheet gains its next Page the moment the content outgrows the last. It re-snaps on the editor'sSizeChanged— the one signal that covers every way the content's height can change (typing, a reload, an Unfold) — coalesced to one snap per dispatcher cycle, since setting the filler resizes the Sheet and lands straight back there. Because the filler rides on the page margin, the Sheet's own height stays the measure of the content: subtracting the filler back off recovers it; -
hands the paper to the DocumentSheetBackdrop by making the editor's
Backgroundtransparent, so the Sheet's fill and its Page Break rules are drawn behind the Visual Document and a break passes under the text instead of striking through it; -
centres the pair on the canvas natively — the canvas does not scroll horizontally, so it measures
the surface at the viewport width and
HorizontalAlignment=Centercentres it with equal gray margins on both sides, reliably and free of any layout-timing recomputation; -
paints the canvas with
EditorCanvasBrush(darker than the Sheet, so the page edge reads); - follows the caret by scrolling the canvas to keep it in view as the user types or navigates (the editor's own caret-into-view is disabled with its scroll);
- re-points Scroll Sync so the Source Panel syncs to the canvas rather than the editor, which no longer scrolls itself.
On exit it restores every one of these to the plain full-pane surface, and the editor scrolls itself again exactly as before.
Set these on the surface Grid:
| Property | Type | Description |
|---|---|---|
IsEnabled |
bool |
Whether the surface is in Page View. Bind to WorkspaceViewModel.IsPageViewEnabled (on by default). |
Editor |
MarkdownRichEditor |
The editing surface laid out as a Document Sheet. |
Canvas |
ScrollViewer |
The outer scroller the Sheet floats on and that follows the caret. |
Source |
TextBoxBase |
The Source Panel to keep Scroll-Synced with the page. |
Setup |
PageSetup |
The Page Setup the Sheet is laid out under — orientation and Print Margins. Bind to WorkspaceViewModel.PageSetup; left unset, the default (Portrait, Normal margins) applies (INV-061). |
<ScrollViewer x:Name="EditorScroller" Focusable="False"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled">
<Grid controls:PageView.IsEnabled="{Binding IsPageViewEnabled}"
controls:PageView.Editor="{Binding ElementName=Editor}"
controls:PageView.Canvas="{Binding ElementName=EditorScroller}"
controls:PageView.Source="{Binding ElementName=SourcePanel}"
controls:PageView.Setup="{Binding PageSetup}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:EditorGutter Grid.Column="0" Editor="{Binding ElementName=Editor}" />
<!-- Before the editor, so the Sheet is drawn behind it. -->
<controls:DocumentSheetBackdrop Grid.Column="1"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="{Binding ActualWidth, ElementName=Editor}"
Height="{Binding ActualHeight, ElementName=Editor}"
Visibility="{Binding IsPageViewEnabled, Converter={StaticResource BooleanToVisibilityConverter}}" />
<controls:MarkdownRichEditor x:Name="Editor" Grid.Column="1"
Markdown="{Binding ActiveSession.Markdown, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</ScrollViewer>LiveMarkDownEditor
User guide
- Getting Started
- Writing and Formatting
- Tables
- Diagrams
- Files, Folders and Tabs
- Finding and Navigating
- Panels and Layout
- Live Updates and Conflicts
- Pages, Printing and Export
- Spell Check
- Keyboard Shortcuts
Controls
- MarkdownRichEditor
- PageView
- DocumentSheetBackdrop
- PrintPreviewPages
- EditorGutter
- SourceGutter
- OutlinePanel
- FolderPanel
- PanelHeader
- PanelColumn
- CommandBarPanel
- CommandTip
- FindHighlightAdorner
- SpellCheckAdorner
- CodeShadingAdorner
- ChangeHighlightAdorner
- MermaidPreview
- MermaidDiagramView
- DiagramCanvas
- VideoPlayerView