How size a floating toolwindow to it content.

Docking/MDI for WPF Forum

Posted 10 years ago by David Freer
Avatar
I would like for a floating toolwindow to size exactly to its content on initial viewing. How can this be achieved? Thanks in advance.

Comments (14)

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

There is a protected method on DockSite called CreateRaftingWindow. What you could probably do is create a class that inherits DockSite and override that method. If the base method call returns a Window, set SizeToContent on. Then measure it and explicitly set the Width/Height of the Window to what it comes up with. Then turn SizeToContent back off.

SizeToContent needs to be off for things to work properly later on with dynamic docking. We didn't try this idea but hopefully it would work for you.


Actipro Software Support

Posted 10 years ago by David Freer
Avatar
I am just now getting around to attempting your suggestion. I override CreateRaftingWindow as follows:

protected override IRaftingWindow CreateRaftingWindow(RaftingHost raftingHost)
{
var obj = base.CreateRaftingWindow(raftingHost);
var win = obj as Window;
if (win != null)
{
SizeToContent old = win.SizeToContent;
win.SizeToContent = SizeToContent.WidthAndHeight;
//???
win.SizeToContent = old;
}
return obj;
}

Suppose I have the following simple xaml

<docking:ToolWindow x:Name="floatToolWindow" Title="float">
<Rectangle Name="MyRectange" Width="75" Height="75"/>
</docking:ToolWindow>

I am not sure what is to be inserted at //??? in order for the rafted window to be automatically resized to have a client area of 75,75.

Since floating toolwindows with some controls are a staple of design, I am not sure why this functionality is not already built in. Why not provide a

raftedWindow.FloatSizeToContents();
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

We are looking into adding this method now and we'll keep you updated.


Actipro Software Support

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

We've added overloads to the Float method that can be used to size the window to fit the associated content for the next maintenance release.


Actipro Software Support

Posted 10 years ago by David Freer
Avatar
Thanks, that's awesome. After thinking about this more, however, I believe there is a more flexible solution. What about simply having a "SizeToContent" property that takes effect when rafted. The scenario I am concerned about is toolwindows that have expanders. I would want the toolwindow to automatically resize when a child control is expanded/contracted. What to you think?
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

We've marked down a TODO item for that feature, as it is a larger change. There are several controls/containers that would need to be updated to support something like that.


Actipro Software Support

Posted 10 years ago by David Freer
Avatar
If the TODO's don't make it in the next release, could I achieve the desired behavior by calling the new methods you've added whenever the child content has changed (e.g., from a handler of an Expander's expanding event)?
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi David,

In general, yes you can call Float on a floating window (and have the size-to-content code kick in). The problem is that this will create a new hosting window and size it appropriately. So the keyboard focus will probably be lost.

You could implement similar logic to what we are doing to resize the window. The code below works for a given ToolWindow (assuming it's Floating):
Window window = VisualTreeHelperExtended.GetRoot(toolWindow) as Window ?? LogicalTreeHelperExtended.GetRoot(toolWindow) as Window;
if (null != window) {
    window.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    Size desiredSize = window.DesiredSize;
    window.Width = Math.Ceiling(desiredSize.Width);
    window.Height = Math.Ceiling(desiredSize.Height);
    window.Measure(new Size(window.Width, window.Height));
}
But it may not work perfectly in all cases (such as when you have two ToolWindows docked side-by-side).

On a side note, the LogicalTreeHelperExtended.GetRoot has not been released yet so you would need to search up the logical tree manually. Depending on how the ToolWindow is docked, it may or may not be in the visual tree.


Actipro Software Support

Posted 4 months ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Hi,

I am trying to achieve the same behavior. My floating tool window shows or hides some controls depending on the mode and the size of the container should be updated automatically.

I assumed that setting SizeToContentModes="Floating" would do the trick, but it doesn't work for me. Am I missing something?

Your code snippet to change the window size works, but has the described side effect.


Best regards, Tobias Lingemann.

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

Hi Tobias,

The SizeToContentModes="Floating" option should size the root Window to fit the desired size of the tool window, but it only occurs when the tool window is first opened.  After that, it won't automatically update.

Which side effect were you referring to?


Actipro Software Support

Posted 4 months ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Okay, then SizeToContentModes won't work for me.

I am refering to the case where the tool window is docked with another window:

But it may not work perfectly in all cases (such as when you have two ToolWindows docked side-by-side).

In that case I don't need to resize the window. But how do I find out if its the only tool window in the container?


Best regards, Tobias Lingemann.

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

You might be able to walk up the visual tree and see the ToolWindow.ToolWindowContainer (if not null) is in an ancestor SplitContainer.  If so, check for any other containers in SplitContainer.Children to see if there are any ToolWindowContainer instances that have their Windows collection populated.  The ToolWindowContainer.Windows collection may be empty if you had a tool window in a container but then closed the tool window.  In that case, a breadcrumb is left behind.


Actipro Software Support

Posted 4 months ago by Tobias Lingemann - Software Devolpment Engineer, Vector Informatik GmbH
Avatar

Okay, I think this will work:

private static bool IsToolWindowAloneInContainer(DockingWindow dockingWindow)
{
  var splitContainer = VisualTreeHelperExtended.GetAncestor<SplitContainer>(dockingWindow);
  if (splitContainer == null)
  {
    if (dockingWindow.ParentContainer is ToolWindowContainer container)
    {
      return container.Windows.Count == 1;
    }

    return true;
  }

  return VisualTreeHelperExtended.GetAllDescendants<ToolWindowContainer>(splitContainer).Count <= 1;
}


Best regards, Tobias Lingemann.

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

Hi Tobias,

We are adding a DockHost.GetVisibleToolWindowContainerCount() method in the upcoming build that will help you and have some improved logic.  I'd recommend switching to that once it's available.  You can get the current DockHost from the DockingWindow.DockHost property.


Actipro Software Support

The latest build of this product (v2019.1 build 0685) was released 11 days ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.