Docking + MVVM + some vertical ToolWindow

Docking/MDI for WPF Forum

Posted 4 years ago by Alex4
Version: 14.2.0611
Avatar

Hello. I would like to migrate to a library of your company. But I have a question. How can I implement this interface using MVVM. I mean two vertical ToolWindow on the left side the dock in the middle and the ToolWindow on the right side plus ToolWindow below.

Comments (7)

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

Our Sample Browser project has an open source attached behavior for working with MVVM to determine where tool windows open.  It is in the /ProductSamples/DockingSamples/Common/DockSiteViewModelBehavior class. Specifically, the OpenDockingWindow method in that class is what is positioning the tool windows.  It is looking at the view models, at properties like their DefaultDock property, and determining what to do there.

Since it's open source, you can modify it however you like.  You can add other properties to the view models that say dock relative to another tool window.  Then just update that OpenDockingWindow method to call toolWindow.Dock(targetToolWindow, relativeDirection).

To get the layout you are wanting, the order of the tool windows being opened is going to be important.  I would think you should do something like:

  1. Solution Explorer - Dock left relative to the DockSite.
  2. Class View - Dock bottom relative to the Solution Explorer tool window.
  3. Document Outline - Dock right relative to the DockSite.
  4. Output - Dock bottom relative to the DockSite.

I hope that helps.


Actipro Software Support

Posted 4 years ago by Alex4
Avatar

Thank you very much for your help.I almost did what I want, but I can't set the size.

Now I get this application.

but I would like that my app looked like this.

How can I set the size?

My test app

[Modified 4 years ago]

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello, I believe that if you do this line on a tool window prior to docking, it will let you set a desired size:

DockSite.SetControlSize(toolWindow, new Size(200, 100));


Actipro Software Support

Posted 4 years ago by Alex4
Avatar

I added DockSite.SetControlSize in OpenDockingWindow and I got a strange result.

My OpenDockingWindow

private static void OpenDockingWindow(DockSite dockSite, DockingWindow dockingWindow)
        {
            if (!dockingWindow.IsOpen)
            {
                if (dockingWindow is DocumentWindow)
                {
                    dockingWindow.Open();
                }
                else
                {
                    DockSite.SetControlSize(dockingWindow, new Size(150, 100));

                    var toolWindow = dockingWindow as ToolWindow;
                    var toolItemViewModel = dockingWindow.DataContext as ToolItemViewModel;
                    if (toolWindow != null && toolItemViewModel != null)
                    {
                        // Look for a ToolWindow within the same group, if found then dock to that group, otherwise either dock or auto-hide the window
                        ToolWindow targetToolWindow = GetToolWindow(dockSite, toolItemViewModel.DockGroup);
                        if (targetToolWindow != null && targetToolWindow != toolWindow)
                        {
                            toolWindow.Dock(targetToolWindow, GetDirection(toolItemViewModel.Direction));
                        }
                        else if (toolItemViewModel.IsInitiallyAutoHidden)
                        {
                            toolWindow.AutoHide(toolItemViewModel.DefaultDock);
                        }
                        else
                        {
                            toolWindow.Dock(dockSite, toolItemViewModel.DefaultDock);
                        }
                    }
                    else
                    {
                        dockingWindow.Open();
                    }
                }
            }
        }

 My MainWindowViewModel

public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            this.DocumentItems = new ObservableCollection<DocumentItemViewModel>();
            this.ToolItems = new ObservableCollection<ToolItemViewModel>();

            var richTextDocumentItemViewModel = new RichTextDocumentItemViewModel();
            richTextDocumentItemViewModel.FileName = @"C:\Users\Actipro\My Documents\WelcomeDocument.rtf";
            this.DocumentItems.Add(richTextDocumentItemViewModel);

            var classViewToolItemViewModel = new ClassViewToolItemViewModel();
            classViewToolItemViewModel.DefaultDock = Dock.Left;
            classViewToolItemViewModel.Direction = Direction.ContentTop;
            classViewToolItemViewModel.DockGroup = "Group1";
            this.ToolItems.Add(classViewToolItemViewModel);

            var classViewToolItemViewModel1 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel1.DefaultDock = Dock.Left;
            classViewToolItemViewModel1.DockGroup = "Group1";
            classViewToolItemViewModel1.Direction = Direction.ContentTop;
            this.ToolItems.Add(classViewToolItemViewModel1);

            var classViewToolItemViewModel4 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel4.DefaultDock = Dock.Left;
            classViewToolItemViewModel4.DockGroup = "Group1";
            classViewToolItemViewModel4.Direction = Direction.ContentTop;
            this.ToolItems.Add(classViewToolItemViewModel4);

            var classViewToolItemViewModel5 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel5.DefaultDock = Dock.Left;
            classViewToolItemViewModel5.DockGroup = "Group1";
            classViewToolItemViewModel5.Direction = Direction.Content;
            this.ToolItems.Add(classViewToolItemViewModel5);

            var classViewToolItemViewModel2 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel2.DefaultDock = Dock.Right;
            classViewToolItemViewModel2.DockGroup = "Group3";
            classViewToolItemViewModel2.Direction = Direction.Content;
            this.ToolItems.Add(classViewToolItemViewModel2);

            var classViewToolItemViewModel3 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel3.DefaultDock = Dock.Bottom;
            classViewToolItemViewModel3.DockGroup = "Group4";
            classViewToolItemViewModel3.Direction = Direction.Content;
            this.ToolItems.Add(classViewToolItemViewModel3);
        }

        public ObservableCollection<DocumentItemViewModel> DocumentItems { get; set; }

        public ObservableCollection<ToolItemViewModel> ToolItems { get; set; }

    }

 

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

You are telling every tool window to try and have a certain height but you don't have room to support the sum of those heights so the layout has to compensate.  With how MVVM gets loaded, you are adding tool windows one at a time to the layout and each time a tool window gets added, it has to consider the currently available size.  Thus adding three tool windows on the left docked against each other with desired heights of 150 but an available height of less than 460 (space includes splitter height) will not yield three tool windows of equal height.  If on the other hand, everything was set up in XAML with those default sizes and less than 460 available height, they should end up the same height because the XAML would load the entire layout at once.

I would recommend that you have some property on your view model where you only change the default size for specific windows.  Perhaps use a Size? (nullable) property and only call SetControlSize if that is set.

Either that or configure the layout how you want at runtime and then serialize the layout out to an XML file using our serialization code.  Then restore that layout the next app session.


Actipro Software Support

Posted 4 years ago by Alex4
Avatar

Hello. I added Size in the Viewmodel but it did not help.

 if (toolWindow != null && toolItemViewModel != null)
                    {
                        if (toolItemViewModel.Size.HasValue)
                        {
                            DockSite.SetControlSize(dockingWindow, toolItemViewModel.Size.Value);
                        }

I tried various combinations, but the left side does not respond to the set size. I also tried to disable the right and bottom side but it did not help.

 

public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            this.DocumentItems = new ObservableCollection<DocumentItemViewModel>();
            this.ToolItems = new ObservableCollection<ToolItemViewModel>();

            var richTextDocumentItemViewModel = new RichTextDocumentItemViewModel();
            richTextDocumentItemViewModel.FileName = @"C:\Users\Actipro\My Documents\WelcomeDocument.rtf";
            this.DocumentItems.Add(richTextDocumentItemViewModel);

            var classViewToolItemViewModel = new ClassViewToolItemViewModel();
            classViewToolItemViewModel.DefaultDock = Dock.Left;
            classViewToolItemViewModel.Direction = Direction.ContentTop;
            classViewToolItemViewModel.DockGroup = "Group1";
            classViewToolItemViewModel.Size = new Size(150, 100);
            this.ToolItems.Add(classViewToolItemViewModel);

            var classViewToolItemViewModel1 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel1.DefaultDock = Dock.Left;
            classViewToolItemViewModel1.DockGroup = "Group1";
            classViewToolItemViewModel1.Direction = Direction.ContentTop;
            classViewToolItemViewModel1.Size = new Size(150, 100);
            this.ToolItems.Add(classViewToolItemViewModel1);

            var classViewToolItemViewModel4 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel4.DefaultDock = Dock.Left;
            classViewToolItemViewModel4.DockGroup = "Group1";
            classViewToolItemViewModel4.Direction = Direction.ContentTop;
            classViewToolItemViewModel4.Size = new Size(150, 100);
            this.ToolItems.Add(classViewToolItemViewModel4);

            var classViewToolItemViewModel5 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel5.DefaultDock = Dock.Left;
            classViewToolItemViewModel5.DockGroup = "Group1";
            classViewToolItemViewModel5.Direction = Direction.Content;
            classViewToolItemViewModel5.Size = new Size(150, 100);
            this.ToolItems.Add(classViewToolItemViewModel5);

            var classViewToolItemViewModel2 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel2.DefaultDock = Dock.Right;
            classViewToolItemViewModel2.DockGroup = "Group3";
            classViewToolItemViewModel2.Direction = Direction.Content;
            this.ToolItems.Add(classViewToolItemViewModel2);

            var classViewToolItemViewModel3 = new ClassViewToolItemViewModel();
            classViewToolItemViewModel3.DefaultDock = Dock.Bottom;
            classViewToolItemViewModel3.DockGroup = "Group4";
            classViewToolItemViewModel3.Direction = Direction.Content;
            classViewToolItemViewModel3.Size = new Size(150, 100);
            this.ToolItems.Add(classViewToolItemViewModel3);
        }

 

<controls:WindowEx xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking"
                   xmlns:behaviors="clr-namespace:Xaml.Behaviors;assembly=Xaml"
                   xmlns:controls="clr-namespace:Xaml.Controls;assembly=Xaml"
                   x:Class="WpfApplication3.Views.MainWindow"
                   Title="MainWindow"
                   Height="500"
                   Width="780">

    <controls:WindowEx.Resources>

        <!-- docking:DockingWindow -->
        <Style x:Key="DockingItemStyle"
               TargetType="docking:DockingWindow">
            <Setter Property="Description"
                    Value="{Binding Description}" />
            <Setter Property="ImageSource"
                    Value="{Binding ImageSource}" />
            <Setter Property="Title"
                    Value="{Binding Title}" />
        </Style>

        <!-- docking:DocumentWindow -->
        <Style x:Key="DocumentItemStyle"
               TargetType="docking:DocumentWindow"
               BasedOn="{StaticResource DockingItemStyle}">
            <Setter Property="FileName"
                    Value="{Binding FileName}" />
            <Setter Property="IsReadOnly"
                    Value="{Binding IsReadOnly}" />
        </Style>

        <!-- docking:ToolWindow -->
        <Style x:Key="ToolItemStyle"
               TargetType="docking:ToolWindow"
               BasedOn="{StaticResource DockingItemStyle}">
            <!--<Setter Property="Height"
                    Value="100" />-->
        </Style>

    </controls:WindowEx.Resources>

    <!-- DockSite -->
    <!-- Note: DockSiteViewModelBehavior.IsManaged should be set first so event handlers are hooked up before items are added -->
    <docking:DockSite x:Name="dockSite"
                      behaviors:DockSiteViewModelBehavior.IsManaged="true"
                      CanDocumentWindowsRaft="True"
                      ItemContainerRetentionMode="Wrapped"
                      DocumentItemsSource="{Binding DocumentItems}"
                      DocumentItemContainerStyle="{StaticResource DocumentItemStyle}"
                      ToolItemsSource="{Binding ToolItems}"
                      ToolItemContainerStyle="{StaticResource ToolItemStyle}">
        <docking:Workspace>
            <docking:TabbedMdiHost />
        </docking:Workspace>
    </docking:DockSite>
</controls:WindowEx>
Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello, please zip up your sample and email it to our support address and reference this thread.  In your email, tell us exactly what you are trying to achieve with the left side and we'll debug it.  Be sure to rename the .zip file extension of what you send so it doesn't get spam blocked.  Thanks!


Actipro Software Support

The latest build of this product (v2018.1 build 0675) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.