xceedsoftware / wpftoolkit

All the controls missing in WPF. Over 1 million downloads.
Other
3.87k stars 872 forks source link

LayoutAnchorable.AddToLayout throws InvalidOperationException and I do not know how to correct the code #1517

Open silviubogan opened 5 years ago

silviubogan commented 5 years ago

I have the following working XAML:

<xcad:DockingManager AllowMixedOrientation="True" Name="MyDockingManager">
    <xcad:LayoutRoot>
        <xcad:LayoutRoot.LeftSide>
            <xcad:LayoutAnchorSide>
                <xcad:LayoutAnchorGroup>
                    <xcad:LayoutAnchorable CanClose="False" Title="Group List" x:Name="MyGroupListAnchorable"
                                        ContentId="MyGroupListAnchorable">
                        <local:ClockGroupListView
                        x:Name="MyClockGroupListView"
                        HorizontalAlignment="Stretch" 
                        ZoomFactor="1" VerticalAlignment="Stretch"
                        MyDataFile="{Binding Path=DataFile, ElementName=MyViewsGrid}"
                        FocusedZoomableSubcontrolChanged="MyClockGroupListView_FocusedZoomableSubcontrolChanged"
                        IsKeyboardFocusWithinChanged="MyClockGroupListView_IsKeyboardFocusWithinChanged"
                        ScrollChanged="MyClockGroupListView_ScrollChanged"
                        />
                    </xcad:LayoutAnchorable>
                </xcad:LayoutAnchorGroup>
            </xcad:LayoutAnchorSide>
        </xcad:LayoutRoot.LeftSide>

        <xcad:LayoutPanel>
            <xcad:LayoutAnchorablePaneGroup>
                <xcad:LayoutAnchorablePane>
                    <xcad:LayoutAnchorable CanClose="False" Title="Flow View" x:Name="MyFlowViewAnchorable"
                                        ContentId="MyFlowViewAnchorable">
                        <local:ClockFlowLayoutPanel x:Name="MyFlowView"
                        DataFile="{Binding Path=DataFile, ElementName=MyViewsGrid}" Background="White" ZoomFactor="1" IsKeyboardFocusWithinChanged="MyFlowView_IsKeyboardFocusWithinChanged"
                            ScrollChanged="MyFlowView_ScrollChanged"
                            />
                    </xcad:LayoutAnchorable>

                    <xcad:LayoutAnchorable CanClose="False" Title="Data Grid" x:Name="MyDataGridAnchorable"
                                        ContentId="MyDataGridAnchorable">
                        <local:ClockDataGrid x:Name="MyDataGrid"
                    Clocks="{Binding Path=DataFile.ClockVMCollection, ElementName=MyViewsGrid}" ZoomFactor="1" IsKeyboardFocusWithinChanged="MyDataGrid_IsKeyboardFocusWithinChanged"
                        ScrollChanged="MyDataGrid_ScrollChanged"/>
                    </xcad:LayoutAnchorable>
                </xcad:LayoutAnchorablePane>
            </xcad:LayoutAnchorablePaneGroup>
        </xcad:LayoutPanel>
    </xcad:LayoutRoot>
</xcad:DockingManager>

In code-behind, when the user executes a command, I use this call:

MyFlowViewAnchorable.AddToLayout(MyDockingManager, Xceed.Wpf.AvalonDock.Layout.AnchorableShowStrategy.Top);

But since IsHidden is true, I get the exception InvalidOperationException here.

I use the latest AvalonDock code (v3.5) and .NET Framework v4.7.2.

Thank you.

Dirkster99 commented 5 years ago

Hi, would you be able to provide a reproducable complete sample of your problem using my AvalonDock branch and either a demo project of your own or by extending an available project?

I wonder if this problem is not already solved in my branch, or if not, whether we can solve it there?

silviubogan commented 5 years ago

Thank you for your interest! I reproduced the problem here but I am not sure how to correctly load your AvalonDock package. If I put the same code (the same XAML and the Click handler of the button in the top of the window) in a modified version of your AvalonDock demo project (TestApp), it has the same bug. Maybe I do not know how to use the AvalonDock API.

silviubogan commented 5 years ago

I used this step by step. I got all the generated Release DLLs of the modified ExtendedWPFToolkit as downloaded from the official GitHub repo, I copied them near the Release executable of the test project and replaced the DLLs of the official version of AvalonDock and I double click the executable (cs-extended-wpf-test-1.exe. No window is displayed, but a loading mouse cursor shows up and disappears very fast. The LiveExplorer in the modified toolkit folder shows up and runs well (I entered just the AvalonDock section) but I do not know what to look up for, maybe a visual distinction in LiveExplorer that I can see.

Dirkster99 commented 5 years ago

Hi, I've cloned your repository and replaced your Toolkit reference in NuGet with Dirkster.AvalonDock. This works in your case because you are not using anything beyond AvalonDock from the XceedToolkit.

The AvalonDock control library originated from a different author (see Introduction of linked article) than Xceed which is why it is only artificially included in the Xceed Toolkit while it is in fact technically independent (at least as far as the open source version is concerned).

The guide that I wrote was indented for those who want to use Dirkster.AvalonDock with additional (other than AvalonDock) components from the Xceed toolkit (I don't think you need the Xceed toolkit right now, at least not in your test program).

You can follow along the codeproject guide to learn more about how AvalonDock was intendet to be used - and yes - your usage of the API does not look correct to me (which is why your problem can be verified with both versions of the library). AvalonDock requires that your are familiar with the MVVM pattern. You should, for example, know how to bind a collection to an ItemsControl and insert a new item during run time etc.. things like this will either help you to display new LayoutAnchorables at run time or another way would be to change the Xml Layout via saving and loading.

Either way, you are not looking at a simple problem and/or solution I am afraid. So, maybe it is helpful to follow the Codeproject series of articles first (you should only need different namespaces to use version 3.x the rest ist still very similar) and then come back to addressing this problem when you have a better understanding about AvalonDock's basic usage patterns.

silviubogan commented 5 years ago

Thank you for your help! I think I will read the articles and, if what I want to achieve is not possible in another way, I will use XML layout saving and loading.

XceedBoucherS commented 5 years ago

Hello, You mean you have the InvalidOperationException because the IsVisible property is true, not the IsHidden property.

From what I understand, you want to add "MyFlowViewAnchorable" to the DockingManager when the user executes a command. But the "MyFlowViewAnchorable" is already part of the DockingManager.

What you can do is to create a new LayoutAnchorable and add it to the DockingManager, here's an example: private void Button_Click( object sender, RoutedEventArgs e ) { var la = new LayoutAnchorable() { CanClose = false, Title = "MyNewLayoutAnchorable", ContentId = "MyNewLayoutAnchorable" }; la.Content = new Button() { Content = "TESTING" }; la.AddToLayout( MyDockingManager, Xceed.Wpf.AvalonDock.Layout.AnchorableShowStrategy.Top ); }