0

I'm using Dirkster AvalonDock(v4.60.1) with MVVM pattern.

Avalon Dock usually setup the LayoutUpdateStrategy as below: (In XAML)

<avalonDock:DockingManager.LayoutUpdateStrategy>
    <helper:LayoutInitializer/>
</avalonDock:DockingManager.LayoutUpdateStrategy>

However, I need to change the anchorable view to Float/Hide manually through my ViewModel, therefore the way I think can be done is to create the LayoutInitializer class in my ViewModel and bind it to the XAML in order for my ViewModel to access the AvalonDock Element(eg. LayoutRoot, LayoutAnchorable, Container, etc.).

How can I create the LayoutInitializer class in my ViewModel and bind it to <avalonDock:DockingManager.LayoutUpdateStrategy> in XAML?

  • both of the two seems to be ui elements and not business logic, so why do you want the `helper:LayoutInitializer` in vm? any benifit? – Lei Yang Jan 26 '22 at 06:06
  • @LeiYang, From my understanding of Avalon Dock MVVM pattern, the only place to change the view state (Floating Window/Docking Window/Hide Window) is in the LayoutInitializer class. For my case, I need to change the view state manually in my ViewModel, therefore I am finding a way to create the LayoutInitializer class over my ViewModel(so that my VM can access the UI Element to change the view state) and meanwhile sharing the same class with the View to prevent duplicate creation. Yes, I can create the LayoutInitializer class in VM but I have no idea how to bind it with the View. – Joshua Chan Jan 26 '22 at 06:32
  • 1
    MVVM is a set of guidelines, not rules. so if you already create a `LayoutInitializer` in vm, why not also have `DockingManager.LayoutUpdateStrategy`? – Lei Yang Jan 26 '22 at 06:37

1 Answers1

2

Beating my head against the wall for the entire week and I forgot to try the simplest binding method.

Thanks to @Lei Yang, for reminding me (at the comment section):

Since I can create the helper:LayoutInitializer over my ViewModel, then obviously I can bind my entire DockingManager.LayoutUpdateStrategy to that created helper:LayoutInitializer class.

Instead of writing the XAML code to create that helper:LayoutInitializer class:

<avalonDock:DockingManager.LayoutUpdateStrategy>
    <helper:LayoutInitializer/>
</avalonDock:DockingManager.LayoutUpdateStrategy>

I can bind it over the Docking Manager,

<avalonDock:DockingManager x:Name="dockManager"
                                   AnchorablesSource="{Binding TVm}"
                                   DocumentsSource="{Binding CVM}"
                                   ActiveContent="{Binding ActiveDocument, Mode=TwoWay, Converter={StaticResource ActiveDocumentConverter}}"
                                   Background="WhiteSmoke"
                                   LayoutUpdateStrategy="{Binding ADLayoutStrategy}">...

Above code does the magic, as you can see the last row of the avalonDock:DockingManager. I bind the LayoutUpdateStrategy to a property of my ViewModel and that property is pointing to my helper:LayoutInitializer class.

LayoutInitializer ADLayoutStrategy = new LayoutInitializer();

Now, the ViewModel can access the UIElement and change the document/anchorable view state!

I don't know is there anyone still using AvalonDock out there, but hope it helps!