Dockingmanager.SetState(element, DockState.Hidden) => Hidden state is not allowed

Dear Syncfusion team,

I have a project with a DockingManager. I am trying to call Dockingmanager.SetState(element, DockState.Hidden), but it results in an exception with message Hidden state is not allowed.

I can call

Dockingmanager.SetState(element, DockState.Dock) and

Dockingmanager.SetState(element, DockState.AutoHidden) without issue, but not

Dockingmanager.SetState(element, DockState.Hidden).

Below is the StrackTrace.

System.InvalidOperationException

  HResult=0x80131509

  Message=Hidden state is not allowed

  Source=Syncfusion.Tools.Wpf

  StackTrace:

   at Syncfusion.Windows.Tools.Controls.DockingManager.CoerceState(DependencyObject d, Object value)

   at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks)

   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)

   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)

   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)

   at Syncfusion.Windows.Tools.Controls.DockingManager.SetState(DependencyObject obj, DockState value)

   at SyncfusionHelperLibrary.Controls.DockingControl.DockingManagerActivateChildWindowBehavior.SetStateOrActivateWindow(DockingManager dockingManager, String controlHeader, List`1 mainWindowNames, List`1 fullWidthWindowNames) in C:\Users\nvans\source\repos\HealthcareRegistrationSolution\SyncfusionHelperLibrary\Controls\DockingControl\DockingManagerActivateChildWindowBehavior.cs:line 75


  This exception was originally thrown at this call stack:

    Syncfusion.Windows.Tools.Controls.DockingManager.CoerceState(System.Windows.DependencyObject, object)

    System.Windows.DependencyObject.ProcessCoerceValue(System.Windows.DependencyProperty, System.Windows.PropertyMetadata, ref System.Windows.EntryIndex, ref int, ref System.Windows.EffectiveValueEntry, ref System.Windows.EffectiveValueEntry, ref object, object, object, System.Windows.CoerceValueCallback, bool, bool, bool)

    System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, ref System.Windows.EffectiveValueEntry, bool, bool, System.Windows.OperationType)

    System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty, object, System.Windows.PropertyMetadata, bool, bool, System.Windows.OperationType, bool)

    System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty, object)

    Syncfusion.Windows.Tools.Controls.DockingManager.SetState(System.Windows.DependencyObject, Syncfusion.Windows.Tools.Controls.DockState)

    SyncfusionHelperLibrary.Controls.DockingControl.DockingManagerActivateChildWindowBehavior.SetStateOrActivateWindow(Syncfusion.Windows.Tools.Controls.DockingManager, string, System.Collections.Generic.List<string>, System.Collections.Generic.List<string>) in DockingManagerActivateChildWindowBehavior.cs

In a seperate assem,bly I created a Usercontrol with the DockingManager

        <sf:DockingManager

            x:Name="DockingManagerControl"

            UseDocumentContainer="True"

            Loaded="DockingManagerControl_Loaded"

            ActiveWindowChanged="DockingManagerControl_ActiveWindowChanged"

            local:DockingManagerActivateChildWindowBehavior.ActivateOnMessage="True"/>


Here is DockingManagerActivateChildWindowBehavior :

public static readonly DependencyProperty ActivateOnMessageProperty = DependencyProperty.RegisterAttached(

        "ActivateOnMessage",

        typeof(bool),

        typeof(DockingManagerActivateChildWindowBehavior),

        new PropertyMetadata(false, OnActivateOnMessageChanged));


        public static bool GetActivateOnMessage(DependencyObject obj)

        {

            return (bool)obj.GetValue(ActivateOnMessageProperty);

        }


        public static void SetActivateOnMessage(DependencyObject obj, bool value)

        {

            obj.SetValue(ActivateOnMessageProperty, value);

        }


        private static void OnActivateOnMessageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            if (d is DockingManager dockingManager && e.NewValue is bool shouldActivate)

            {

                if (shouldActivate)

                {

                    WeakReferenceMessenger.Default.Register<ActivateWindowEvent>(dockingManager, OnActivateWindowMessageReceived);

                }

                else

                {

                    WeakReferenceMessenger.Default.Unregister<ActivateWindowEvent>(dockingManager);

                }

            }

        }


        private static void OnActivateWindowMessageReceived(object recipient, ActivateWindowEvent message)

        {

            if (recipient is DockingManager dockingManager)

            {

                if (message.Value.Contains("HeaderContact", StringComparison.OrdinalIgnoreCase))

                {

                    // for testing only

                    SetDockStateContactHeader(dockingManager, true);

                }

                else

                {

                    SetStateOrActivateWindow(dockingManager, message.Value, message.MainWindowNames, message.FullWidthWindowNames);

                }

            }

        }


        private static void SetStateOrActivateWindow(DockingManager dockingManager, string controlHeader, List<string> mainWindowNames, List<string> fullWidthWindowNames)

        {

            try

            {

                foreach (FrameworkElement element in dockingManager.Children)

                {

                    string elementHeader = (string)DockingManager.GetHeader(element);

                    DockState elementState = DockingManager.GetState(element);


                    if (IsElementInMainWindowNamesAndDocked(element, mainWindowNames))

                    {

                        try

                        {

                            DockingManager.SetState(element, DockState.Hidden);

                        }

                        catch (Exception exState)

                        {


                        }

                    }


                    //if (string.Equals(elementHeader, controlHeader, StringComparison.OrdinalIgnoreCase))

                    if (elementHeader.Contains(controlHeader, StringComparison.OrdinalIgnoreCase) || controlHeader.IndexOf(elementHeader, StringComparison.OrdinalIgnoreCase) >= 0)

                    {

                        if (elementState == DockState.Hidden)

                        {

                            ShowElement(dockingManager, element, mainWindowNames, fullWidthWindowNames);

                        }

                        else if (dockingManager.ActiveWindow != element && elementState == DockState.AutoHidden)

                        {

                            dockingManager.ActivateWindow(element.Name);

                        }

                    }

                }

            }

            catch (Exception ex)

            {

                //_logger.LogError(ex, "Error occurred in SetStateOrActivateWindow.");

            }

        }


        /// <summary>

        /// Shows the given element and sets the appropriate width and dock state for the contact header.

        /// </summary>

        /// <param name="element">The element to show.</param>

        private static void ShowElement(DockingManager dockingManager, FrameworkElement element, List<string> mainWindowNames, List<string> fullWidthWindowNames)

        {

            DockingManager.SetState(element, DockState.Dock);


            if (fullWidthWindowNames.Contains(element.Name, StringComparer.OrdinalIgnoreCase))

            {

                DockingManager.SetDesiredWidthInDockedMode(element, SystemParameters.PrimaryScreenWidth - 50);

                SetDockStateContactHeader(dockingManager, false);

            }

            else

            {

                if (DockingManager.GetDesiredWidthInDockedMode(element) == 90)

                {

                    DockingManager.SetDesiredWidthInDockedMode(element, SystemParameters.PrimaryScreenWidth - 550);

                }


                SetDockStateContactHeader(dockingManager, true);

            }

        }


        /// <summary>

        /// Sets the dock state of the ContactHeaderViewModel based on the provided boolean flag.

        /// </summary>

        /// <param name="setIsDocked">True to set the dock state to Dock, false to set it to Hidden.</param>

        private static void SetDockStateContactHeader(DockingManager dockingManager, bool setIsDocked)

        {

            try

            {

                foreach (FrameworkElement element in dockingManager.Children)

                {

                    if (element.Name.Contains("HeaderContact", StringComparison.OrdinalIgnoreCase))

                    {

                        DockingManager.SetState(element, setIsDocked ? DockState.Dock : DockState.Hidden);

                    }

                }

            }

            catch (Exception ex)

            {

                //_logger.LogError(ex, "Error occurred in SetDockStateContactHeader.");

            }

        }

    

        /// <summary>

        /// Checks if the element is in the Main WindowName list and if it's docked.

        /// </summary>

        /// <param name="element">The FrameworkElement to check.</param>

        /// <returns>True if the element is in the list and docked, otherwise false.</returns>

        private static bool IsElementInMainWindowNamesAndDocked(FrameworkElement element, List<string> mainWindowNames)

        {

            return mainWindowNames.Exists(vmName => string.Equals(element.Name, vmName, StringComparison.OrdinalIgnoreCase) && DockingManager.GetState(element) == DockState.Dock);

        }

I am using CommunityToolkit.Mvvm and am trying to switch the DockState of a ViewModel based on a message that is received by the adapter. It works fine to set ViewModels to DockState.Dock but not to set the same ViewModels to DockState.Hidden.


Any help would be appreciated.


Niels van Strien




1 Reply 1 reply marked as answer

NV NM van Strien May 18, 2023 09:08 PM UTC

I mistakenly set CanClose = false when initializing the viewmodels, so that was blocking the DockState.Hidden.


This issue can be closed  - not a bug.


Kind regards,


Niels van Strien


Marked as answer
Loader.
Up arrow icon