dotnet/wpf · error · ArgumentException

SR.FlowDocumentReaderCannotDisableAllViewingModes

Error message

SR.FlowDocumentReaderCannotDisableAllViewingModes

What it means

FlowDocumentReader throws this ArgumentException from the IsPageViewEnabled / IsTwoPageViewEnabled / IsScrollViewEnabled property change callbacks when a setter would disable the last remaining enabled viewing mode. At least one viewing mode must always be available, otherwise the reader could not render its document at all.

Solutions

  1. Ensure at least one of IsPageViewEnabled, IsTwoPageViewEnabled, IsScrollViewEnabled stays true when changing them.
  2. Compute the flags together and leave the currently-used mode enabled, then apply them in an order that never disables the last one.
  3. Validate user/config input so an all-false view configuration is rejected before it reaches the reader.

Example fix

// before
reader.IsPageViewEnabled = false;
reader.IsTwoPageViewEnabled = false;
reader.IsScrollViewEnabled = false; // throws

// after
var enabled = new[] { false, false, true }; // at least one true
reader.IsPageViewEnabled = enabled[0];
reader.IsTwoPageViewEnabled = enabled[1];
reader.IsScrollViewEnabled = enabled[2];
Defensive patterns

Strategy: validation

Validate before calling

if (!allowPage && !allowTwoPage && !allowScroll)
    throw new InvalidOperationException("At least one viewing mode must remain enabled.");
reader.IsPageViewEnabled = allowPage;
reader.IsTwoPageViewEnabled = allowTwoPage;
reader.IsScrollViewEnabled = allowScroll;

Try / catch

try { ApplyViewFlags(reader, flags); }
catch (ArgumentException ex) { logger.Warn(ex); ApplyViewFlags(reader, (true, false, false)); }

Prevention

When it happens

Trigger: Setting IsPageViewEnabled = false, IsTwoPageViewEnabled = false and IsScrollViewEnabled = false (in any order) so that no viewing mode remains enabled.

Common situations: Sequentially disabling views based on config flags where all three evaluate to false; copying an 'enabled views' settings object with all flags off; data binding all three properties to values parsed from an all-zero value.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/a2b6e03d42d9cc99. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/FlowDocumentReader.cs:1648

            return (value == FlowDocumentReaderViewingMode.Page ||
                    value == FlowDocumentReaderViewingMode.TwoPage ||
                    value == FlowDocumentReaderViewingMode.Scroll);
        }

        /// <summary>
        /// One of viewing modes has been enabled/disabled.
        /// </summary>
        private static void ViewingModeEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Invariant.Assert(d != null && d is FlowDocumentReader);
            FlowDocumentReader viewer = (FlowDocumentReader)d;

            // Cannot disable all viewing modes.
            if (!viewer.IsPageViewEnabled &&
                !viewer.IsTwoPageViewEnabled &&
                !viewer.IsScrollViewEnabled)
            {
                throw new ArgumentException(SR.FlowDocumentReaderCannotDisableAllViewingModes);
            }

            // Cannot disable the current viewing mode.
            if (viewer.IsInitialized && !viewer.CanSwitchToViewingMode(viewer.ViewingMode))
            {
                throw new ArgumentException(SR.FlowDocumentReaderViewingModeEnabledConflict);
            }

            // Fire automation events if automation is active.
            FlowDocumentReaderAutomationPeer peer = UIElementAutomationPeer.FromElement(viewer) as FlowDocumentReaderAutomationPeer;
            peer?.RaiseSupportedViewsChangedEvent(e);
        }

        /// <summary>
        /// IsFindEnabled value has changed.
        /// </summary>
        private static void IsFindEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

View on GitHub (pinned to 81131a70a4)