This project is read-only.

[Version 2.0] Create xaml layout for MVVM

May 20, 2012 at 8:33 PM

I have a list of ViewModels to show as anchorable, they are of different types, for example ViewModelA and ViewModelB, I can make a single list for binding to AnchorableSource of the docking manager, I can use different DataTemplate for each ViewModel but I can't decide where the have to be located.

I have to add at runtime elements to this list and I'd like to set in the xaml a reference to an Achorable panel or anchorable panel group in which the must be located.

For example I have to locate all the ViewModels of type ViewModelA in an anchorable on the right side, and all the ViewModels of type ViewModelB on the bottom.

I can't use the serialization of the layout because the items are generated at runtime, the serialization fail because every time I can have different viewModels.

I'd like to make the skeleton of my page layout (for example using only the document panel group and anchorable panel group) and for each of this panel mark the type of view model they will receive, or write in the list of anchorable even a reference to the panel in where the must be located on loading.

Is there any possibility to make something like this?

One solution for me could be to make binding of the list of anchorables not only to the DockingManager but even to each single anchorable panel group.

What do you think, to make the layout of complex application, simpler to be described?

May 21, 2012 at 9:10 AM

I see what you mean, for this task I've already implemented a lockup mechanism based on the LayoutUpdateStrategy. In short, compose the layout as you prefer, give to any anchorable pane of interest a name (I've added the Name property to latest build), lastly write a class implementing the ILayoutUpdateStrategy interface. I've added a sample class to MVVMTestApp showing how it's possible to set the exact layout position of any anchorable created at runtime.

May 25, 2012 at 9:27 AM
Edited May 25, 2012 at 10:28 AM

How can I address the name of the desired destinationContainer? Is there any possibility to assign the name of the anchorablePane to the particular viewModel (-instance)?

May 25, 2012 at 7:07 PM
Edited May 25, 2012 at 7:08 PM

Yes, you can have a property in your view model and then implement your ILayoutUpdateStrategy

For example the ViewModel

 

 

    public class MyViewModel
    {
        public string DestinationPaneName { get; set; }
    }

 

and the ILayoutUpdateStrategy

 

 

    class LayoutInitializer : ILayoutUpdateStrategy
    {
        public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
        {
            var myViewModel = anchorableToShow.Content as MyViewModel;
            if (myViewModel != null)
            {
                var pane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == myViewModel.DestinationPaneName);
                if (pane != null)
                {
                    pane.Children.Add(anchorableToShow);
                    return true;
                }
            }

            return false;
        }

        public bool InsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
        {
            return false;
        }
    }

 

the xaml you must add the name of the panel and the ILayoutUpdateStrategy as in the sample AvalonDock.MVVMTestApp

Jul 4, 2012 at 1:26 PM

Is it possible with some tweak in BeforeInsertAnchorable to add the anchorableToShow to a new floating window?

I want every new tool window to be initially floating in a seperate window.

Jul 4, 2012 at 2:48 PM
MichaelTR wrote:

Is it possible with some tweak in BeforeInsertAnchorable to add the anchorableToShow to a new floating window?

 

I found a solution and hope this is correct:

        public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer)
        {
			LayoutAnchorablePane destPane = destinationContainer as LayoutAnchorablePane;
			if(destPane != null)
			{
				destPane.Children.Add(anchorableToShow);
				anchorableToShow.Float();
				return true;
			}
			return false;
	}

Now the only problem I have is, how can I set the initial size of the floating window to be dependent of my ViewModel?