IsOpen forced to be false when using nested Dock Sites using MVVM

Docking/MDI for WPF Forum

Posted 6 months ago by Jiho Kim - Ansys
Version: 23.1.3
Platform: .NET 4.8
Environment: Windows 11 (64-bit)
Avatar
<UserControl
    x:Class="xxx"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
    xmlns:controls="xxx"
    xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking"
    xmlns:viewModels="xxx">
    <UserControl.Resources>
        <Style
            x:Key="DockSiteStyle"
            BasedOn="{StaticResource {x:Type docking:DockSite}}"
            TargetType="{x:Type controls:CustomDockSite}">
            <Setter Property="AreNewTabsInsertedBeforeExistingTabs" Value="False" />
            <Setter Property="CanDocumentWindowsFloat" Value="False" />
            <Setter Property="CanToolWindowsAttach" Value="True" />
            <Setter Property="CanToolWindowsAutoHide" Value="False" />
            <Setter Property="CanToolWindowsBecomeDocuments" Value="False" />
            <Setter Property="CanToolWindowsFloat" Value="False" />
            <Setter Property="IsLiveSplittingEnabled" Value="False" />
            <Setter Property="Padding" Value="0" />
        </Style>

        <Style x:Key="DockingWindowStyle" TargetType="{x:Type docking:DockingWindow}">
            <Setter Property="IsActive" Value="{Binding Path=IsActive, Mode=TwoWay}" />
            <Setter Property="IsOpen" Value="{Binding Path=IsOpen, Mode=TwoWay}" />
            <Setter Property="SerializationId" Value="{Binding Path=ID, Mode=OneWay}" />
            <Setter Property="Title" Value="{Binding Path=FullName, Mode=TwoWay}" />
        </Style>

        <Style
            x:Key="SlotWindowStyle"
            BasedOn="{StaticResource DockingWindowStyle}"
            TargetType="{x:Type controls:SlotWindow}">
            <Setter Property="HasOptionsButton" Value="False" />
            <Setter Property="HasTitleBar" Value="False" />
            <Setter Property="UseAutoHideTitleBar" Value="True" />
        </Style>

        <Style
            x:Key="SlotGroupWindowStyle"
            BasedOn="{StaticResource DockingWindowStyle}"
            TargetType="{x:Type docking:DocumentWindow}" />

        <controls:SlotViewModelTemplateSelector x:Key="SlotViewModelTemplateSelector" />

        <DataTemplate x:Key="SlotGroupTemplate" DataType="{x:Type viewModels:SlotGroupViewModel}">
            <controls:SlotGroupDockSite
                x:Name="DockSite"
                Layout="{Binding Layout}"
                Style="{StaticResource DockSiteStyle}"
                ToolItemContainerStyle="{StaticResource SlotWindowStyle}"
                ToolItemTemplateSelector="{StaticResource SlotViewModelTemplateSelector}"
                ToolItemsSource="{Binding Items}">
                <docking:SplitContainer>
                    <docking:SplitContainer>
                        <docking:ToolWindowContainer />
                    </docking:SplitContainer>
                </docking:SplitContainer>
            </controls:SlotGroupDockSite>
        </DataTemplate>
    </UserControl.Resources>
    <controls:MainDockSite
        x:Name="DockSite"
        DocumentItemContainerStyle="{StaticResource SlotGroupWindowStyle}"
        DocumentItemTemplate="{StaticResource SlotGroupTemplate}"
        DocumentItemsSource="{Binding Items}"
        Layout="{Binding Layout}"
        Style="{StaticResource DockSiteStyle}">
        <docking:SplitContainer>
            <docking:Workspace>
                <docking:TabbedMdiHost ContainersHaveNewTabButtons="True" />
            </docking:Workspace>
        </docking:SplitContainer>
    </controls:MainDockSite>
</UserControl>

I am attempting to implement nested dock sites using MVVM. However, when the DockSite defined in the SlotGroupTemplate is created, the IsOpen property bound to the ToolWindow becomes false. It has been observed that setting a value to the ToolItemContainerStyle property triggers code that destroys and recreates all DockingWindows.

Here is a step-by-step method to reproduce the issue:
1. Create a SlotGroup (Inner DockSite) and a Slot (ToolWindow).
2. Delete both of them.
3. Recreate SlotGroup and Slot.
4. Change the IsOpen property of the Slot, observed to be false.

<DataTemplate x:Key="SlotGroupTemplate" DataType="{x:Type viewModels:SlotGroupViewModel}">
    <controls:SlotGroupDockSite
        x:Name="DockSite"
        Layout="{Binding Layout}"
        Style="{StaticResource DockSiteStyle}"
        ToolItemContainerStyle="{StaticResource SlotWindowStyle}"
        ToolItemTemplateSelector="{StaticResource SlotViewModelTemplateSelector}">
        <!--  ToolItemsSource="{Binding Items}"  -->
        <behaviors:Interaction.Triggers>
            <behaviors:DataTrigger
                Binding="{Binding ElementName=DockSite, Path=ToolItemContainerStyle}"
                Comparison="NotEqual"
                Value="{x:Null}">
                <behaviors:ChangePropertyAction PropertyName="ToolItemsSource" Value="{Binding Items}" />
            </behaviors:DataTrigger>
        </behaviors:Interaction.Triggers>
        <docking:SplitContainer>
            <docking:SplitContainer>
                <docking:ToolWindowContainer />
            </docking:SplitContainer>
        </docking:SplitContainer>
    </controls:SlotGroupDockSite>
</DataTemplate>

Writing code to bind ToolItemsSource after changing the ToolItemContainerStyle property can resolve the issue. However, I would appreciate it if you could confirm and address this problem.

 

Comments (3)

Posted 6 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

This is a pretty complicated configuration with nesting, custom classes, and data templates.  Please make a new sample project that shows the issue and send that to our support address so we can debug with it.  Try to keep the sample as minimal as possible so it focuses on the specific problem without much unrelated code.  Be sure to exclude the bin/obj folders from the .zip you send so it doesn't get spam blocked.  Thanks!


Actipro Software Support

Posted 6 months ago by Jiho Kim - Ansys
Avatar

I sent you guys a sample by email.

Here's how to reproduce the issue in the sample.
1. uncomment the commented SlotGroupTemplate in MainWindow.xaml and comment the SlotGroupTemplate defined below.
(I created a DataTemplate that avoids the problem, but I didn't comment it out properly. sorry).
2. build and run
3. click "Add Slot"
4. as soon as it is created, IsOpen becomes false (the problem)

If you check the DataTemplate with the behaviours you identified in step 1, you can avoid the problem by binding the ToolItemsSource after the ToolItemContainerStyle is set.
As written in the documentation, the IsOpen property should be changed to false when destroyed, but perhaps there is code that destroys and recreates all ToolWindows the moment the ToolItemContainerStyle is set.

 
 
Answer - Posted 6 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Thank you for the sample.  We've updated some internal logic for the next maintenance release v23.1.4 that should prevent the close.


Actipro Software Support

The latest build of this product (v24.1.2) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.