From 3b5babb5989b11d132c344f664dfda67335b7203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20Wallgren?= Date: Wed, 3 Dec 2025 22:27:32 +0100 Subject: [PATCH 1/2] Make AutoScrollToFirstChange() work reliably in Side-By-Side Diff Both of the SingleSideTextDiffPresenter instances need to be scrolled/synced for this to work reliably. (To see where it failed, open a Side-By-Side Diff where the first change-block would be out-of-view, then toggle `Show All Lines` - when enabling the latter, the first change-block would NOT be correctly scrolled-to.) --- src/Views/TextDiffView.axaml.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 78c4b7137..dac1d7d67 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -805,9 +805,6 @@ private void AutoScrollToFirstChange() if (DataContext is not ViewModels.TextDiffContext ctx) return; - if (ctx.IsSideBySide() && !IsOld) - return; - var curBlock = ctx.BlockNavigation.GetCurrentBlock(); if (curBlock == null) return; From ebc8d2797fcdbb884b5dd789886399ab27986d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20Wallgren?= Date: Wed, 3 Dec 2025 22:35:39 +0100 Subject: [PATCH 2/2] Bonus: Cleanup and simplify the use of Block Navigation * Added private helper method GotoChange(), to remove redundant code. * Made `SyncScrollOffset()` virtual, so the `Goto<...>Change()` methods could be removed. * In `DiffContext.CheckSettings()`, setting the Context is now made on a single (less redundant) line, just like in the `DiffContext.UseSideBySide` setter. --- src/ViewModels/DiffContext.cs | 3 +- src/Views/TextDiffView.axaml.cs | 72 ++++++++++----------------------- 2 files changed, 22 insertions(+), 53 deletions(-) diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index d56a6bc68..8dd965023 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -136,8 +136,7 @@ public void CheckSettings() if (ctx.IsSideBySide() != UseSideBySide) { - ctx = ctx.SwitchMode(); - Content = ctx; + Content = ctx.SwitchMode(); } } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index dac1d7d67..6cc14ae3b 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -487,44 +487,38 @@ public virtual void UpdateSelectedChunk(double y) { } - public virtual void GotoFirstChange() + protected virtual void SyncScrollOffset() { - var first = BlockNavigation.GotoFirst(); - if (first != null) - { - TextArea.Caret.Line = first.Start; - ScrollToLine(first.Start); - } } - public virtual void GotoPrevChange() + private void GotoChange(ViewModels.BlockNavigation.Block block) { - var prev = BlockNavigation.GotoPrev(); - if (prev != null) + if (block != null) { - TextArea.Caret.Line = prev.Start; - ScrollToLine(prev.Start); + TextArea.Caret.Line = block.Start; + ScrollToLine(block.Start); + SyncScrollOffset(); } } - public virtual void GotoNextChange() + public void GotoFirstChange() { - var next = BlockNavigation.GotoNext(); - if (next != null) - { - TextArea.Caret.Line = next.Start; - ScrollToLine(next.Start); - } + GotoChange(BlockNavigation.GotoFirst()); } - public virtual void GotoLastChange() + public void GotoPrevChange() { - var next = BlockNavigation.GotoLast(); - if (next != null) - { - TextArea.Caret.Line = next.Start; - ScrollToLine(next.Start); - } + GotoChange(BlockNavigation.GotoPrev()); + } + + public void GotoNextChange() + { + GotoChange(BlockNavigation.GotoNext()); + } + + public void GotoLastChange() + { + GotoChange(BlockNavigation.GotoLast()); } public override void Render(DrawingContext context) @@ -1095,30 +1089,6 @@ public class SingleSideTextDiffPresenter : ThemedTextDiffPresenter return []; } - public override void GotoFirstChange() - { - base.GotoFirstChange(); - SyncScrollOffset(); - } - - public override void GotoPrevChange() - { - base.GotoPrevChange(); - SyncScrollOffset(); - } - - public override void GotoNextChange() - { - base.GotoNextChange(); - SyncScrollOffset(); - } - - public override void GotoLastChange() - { - base.GotoLastChange(); - SyncScrollOffset(); - } - public override void UpdateSelectedChunk(double y) { if (DataContext is not ViewModels.TwoSideTextDiff diff) @@ -1315,7 +1285,7 @@ private void OnBlockNavigationPropertyChanged(object sender, PropertyChangedEven TextArea?.TextView?.Redraw(); } - private void SyncScrollOffset() + protected override void SyncScrollOffset() { if (_scrollViewer is not null && DataContext is ViewModels.TwoSideTextDiff diff) diff.ScrollOffset = _scrollViewer.Offset;