Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AvalonDock: recommended way to disable hiding behavior for LayoutAnchorable and friends #1500

Open
SirUppyPancakes opened this issue Jun 19, 2019 · 8 comments

Comments

@SirUppyPancakes
Copy link

SirUppyPancakes commented Jun 19, 2019

Somewhat related to #1117

LayoutAnchorable sets CanClose to false by default, and I noticed that the code also does unexpected things like coercing CanClose to false when you tear a LayoutAnchorable off of a LayoutDocumentPane.

My goal is to not have "hiding" behavior at all, as it just creates memory leaks for my use-cases. When a user closes a LayoutAnchorable, I always want it to close permanently.

So far, the only approach I have been able to come up with is to set CanClose and CanHide to true and add these handlers to Closed and Hiding on every single LayoutAnchorable:

        private void PaneClosed(object sender, EventArgs e)
        {
            // closed logic here
        }

        private void PaneHiding(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
            (sender as LayoutContent)?.Close();
        }

This feels super hack-y, but my other attempts to get the behavior I need have failed. Is this the best I can do to get this behavior for now?

@SirUppyPancakes SirUppyPancakes changed the title AvalonDock: recommended way to override CanClose/CanHide/etc on LayoutAnchorable and friends AvalonDock: recommended way to disable hiding behavior for LayoutAnchorable and friends Jun 19, 2019
@XceedBoucherS
Copy link
Collaborator

Hi,

Can you be more precise (maybe by giving a sample code showing the issue) ?
Currently, in v3.5 and up, clicking the "X" button calls the LayoutContent.CloseInternal() method, which removes the LayoutAnchorable from its parent and the CollectGarbage() method finishes the job.
I used a LayoutAnchorable with:
CanHide="False"
CanClose="True"

Thanks.

@SirUppyPancakes
Copy link
Author

Sure thing, I'll upload an example of what I'm talking about when I get a chance this week 👍

@bdachev
Copy link

bdachev commented Sep 2, 2019

Hi Simon,
I'd like to comment on setting CanClose to false for LayoutAnchorable.
Not sure what is the status in Pro version but it surely causes problems in v3.5 which are not fixed yet as promised in #1117.
The issue is as follows:
In LayoutContent base class the default value of CanClose is 'True' and in LayoutContent.WriteXml() method there is an optimization which serializes CanClose property only if its value is not default i.e. if it is 'False'.
Now in v3.3 the default of that property is inverted for class LayoutAnchorable to be 'False' but the serialization is not fixed and thus it is not possible to serialize a value of 'True'.
Now the problem for our project is that when an 'anchorable' is docked in document area it is not possible to hide/close it (the close button is collapsed). Also the tab area looks ugly because of the collapsed (but not hidden) close button.
What is the correct way to use LayoutAnchorable elements so that they can be closed and to be properly serialized/deserialized as a layout?
Hope that all makes sense!
B.

@Dirkster99
Copy link

Hi Boris, would you be able to suggest a change in default or serialization behavior to fix this over in my branch? It seems like someone else has run into the same issue as Simone...

...and we could also Collapse the button instead of Hiding (I was not aware of a layout issue there).

@SirUppyPancakes
Copy link
Author

Finally got the time to throw together a basic example. My first attempt to use AvalonDock was to have dockable panes that could be tabbed in the main area, anchor to any of the four sides, or float and provide another complete new window for others to dock on. I set CanClose to true on all of my LayoutAnchorables, but they realized that closing them when they are floating only hides them, so I also set CanHide to false.

Here is the relevant XAML from the attached example project showing the issue:

        <xcad:DockingManager>
            <xcad:LayoutRoot>
                <xcad:LayoutPanel Orientation="Horizontal">
                    <xcad:LayoutDocumentPaneGroup>
                        <xcad:LayoutDocumentPane>
                            <xcad:LayoutAnchorable x:Name="One" Title="One" ContentId="One" CanClose="True" CanHide="False">
                                <Grid Background="DarkSlateBlue" />
                            </xcad:LayoutAnchorable>
                            <xcad:LayoutAnchorable x:Name="Two" Title="Two" ContentId="Two" CanClose="True" CanHide="False">
                                <Grid Background="DarkRed" />
                            </xcad:LayoutAnchorable>
                            <xcad:LayoutAnchorable x:Name="Three" Title="Three" ContentId="Three" CanClose="True" CanHide="False">
                                <Grid Background="DarkGreen" />
                            </xcad:LayoutAnchorable>
                            <xcad:LayoutAnchorable x:Name="Four" Title="Four" ContentId="Four" CanClose="True" CanHide="False">
                                <Grid Background="OrangeRed" />
                            </xcad:LayoutAnchorable>
                        </xcad:LayoutDocumentPane>
                    </xcad:LayoutDocumentPaneGroup>
                </xcad:LayoutPanel>
                <xcad:LayoutRoot.LeftSide>
                    <xcad:LayoutAnchorSide>
                        <xcad:LayoutAnchorGroup>
                            <xcad:LayoutAnchorable Title="Menu" ContentId="Menu" CanClose="False" CanHide="False" />
                        </xcad:LayoutAnchorGroup>
                    </xcad:LayoutAnchorSide>
                </xcad:LayoutRoot.LeftSide>
            </xcad:LayoutRoot>
        </xcad:DockingManager>

If I don't set CanHide to true, then there will be a close button on floating windows, but that close button will hide the pane instead of closing it (leaking memory in my case). If I set CanHide to false, like above, the close button will not appear at all. I suspect this is just how this was designed (floating windows can't close, only hide), but it really does limit the use-cases. I've personally switched over to a paid docking library that can support the type of use cases I want.

Hope this is clarifies things!

AvalonDockIssue.zip

@bdachev
Copy link

bdachev commented Sep 3, 2019

Hi Boris, would you be able to suggest a change in default or serialization behavior to fix this over in my branch? It seems like someone else has run into the same issue as Simone...

For our project the solution was to remove _canClose = false in LayoutAnchorable constructor thus reverting to original pre v3.3 behavior.

...and we could also Collapse the button instead of Hiding (I was not aware of a layout issue there).

That would probably require adjustments in document tab area template but it seems to me that the button should be Hidden and not Collapsed.

@XceedBoucherS
Copy link
Collaborator

Hi bdachev,
If I used a LayoutAnchorable with:
CanHide="False"
CanClose="True"
in Toolkit v3.5, docking this LayoutAnchorable in a LayoutDocumentPane keeps the the "x" so it is closeable. The same can be valided in the latest v3.8 version. You can test it with the latest version here : https://xceed.com/xceed-toolkit-plus-for-wpf/

For the document tab area, I can't reproduce an ugly (collaped vs hidden) button. Can you in the latest version ?

For the serialization, you got a point. The serialization will always be made for LayoutContent.CanClose in v3.9. Thank you for bringing this to our attention.

@XceedBoucherS
Copy link
Collaborator

Hi SirUppyPancakes ,
You found a bug. Yes, the "X" button is not available for LayoutAnchorable with CanClose set to true when it is created in a LayoutDocumentPane. It would work when docking a LayoutAnchorable inside a LayoutDocumentPane(at least in v3.8), but not from initialization. This issue will be fix in v3.9.

Thank you for bringing this to our attention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants