internal override void Detach()
 {
     _document = null;
     base.Detach();
 }
 public DocumentClosedEventArgs(LayoutDocument document)
 {
     Document = document;
 }
        private void DocumentsSourceElementsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (Layout == null)
                return;

            //When deserializing documents are created automatically by the deserializer
            if (SuspendDocumentsSourceBinding)
                return;

            //handle remove
            if (e.Action == NotifyCollectionChangedAction.Remove ||
                e.Action == NotifyCollectionChangedAction.Replace)
            {
                if (e.OldItems != null)
                {
                    var documentsToRemove =
                        Layout.Descendents()
                            .OfType<LayoutDocument>()
                            .Where(d => e.OldItems.Contains(d.Content))
                            .ToArray();
                    foreach (var documentToRemove in documentsToRemove)
                    {
                        documentToRemove.Parent.RemoveChild(
                            documentToRemove);
                    }
                }
            }

            //handle add
            if (e.NewItems != null &&
                (e.Action == NotifyCollectionChangedAction.Add ||
                 e.Action == NotifyCollectionChangedAction.Replace))
            {
                if (e.NewItems != null)
                {
                    LayoutDocumentPane documentPane = null;
                    if (Layout.LastFocusedDocument != null)
                    {
                        documentPane = Layout.LastFocusedDocument.Parent as LayoutDocumentPane;
                    }

                    if (documentPane == null)
                    {
                        documentPane = Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
                    }

                    _suspendLayoutItemCreation = true;

                    foreach (var documentContentToImport in e.NewItems)
                    {
                        var documentToImport = new LayoutDocument()
                        {
                            Content = documentContentToImport
                        };

                        bool added = false;
                        if (LayoutUpdateStrategy != null)
                        {
                            added = LayoutUpdateStrategy.BeforeInsertDocument(Layout, documentToImport, documentPane);
                        }

                        if (!added)
                        {
                            if (documentPane == null)
                                throw new InvalidOperationException(
                                    "Layout must contains at least one LayoutDocumentPane in order to host documents");

                            documentPane.Children.Add(documentToImport);
                        }

                        LayoutUpdateStrategy?.AfterInsertDocument(Layout, documentToImport);

                        var root = documentToImport.Root;

                        if (root != null && Equals(root.Manager, this))
                        {
                            CreateDocumentLayoutItem(documentToImport);
                        }
                    }
                    _suspendLayoutItemCreation = false;
                }
            }

            if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                //NOTE: I'm going to clear every document present in layout but
                //some documents may have been added directly to the layout, for now I clear them too
                var documentsToRemove = Layout.Descendents().OfType<LayoutDocument>().ToArray();
                foreach (var documentToRemove in documentsToRemove)
                {
                    documentToRemove.Parent.RemoveChild(
                        documentToRemove);
                }
            }
            Layout?.CollectGarbage();
        }
 internal override void Attach(LayoutContent model)
 {
     _document = model as LayoutDocument;
     base.Attach(model);
 }
        private void AttachDocumentsSource(LayoutRoot layout, IEnumerable documentsSource)
        {
            if (documentsSource == null)
                return;

            if (layout == null)
                return;

            var documentsImported = layout.Descendents().OfType<LayoutDocument>().Select(d => d.Content).ToArray();
            var documents = documentsSource;
            var listOfDocumentsToImport = new List<object>(documents.OfType<object>());

            foreach (var document in listOfDocumentsToImport.ToArray().Where(document => documentsImported.Contains(document)))
            {
                listOfDocumentsToImport.Remove(document);
            }

            LayoutDocumentPane documentPane = null;
            if (layout.LastFocusedDocument != null)
            {
                documentPane = layout.LastFocusedDocument.Parent as LayoutDocumentPane;
            }

            if (documentPane == null)
            {
                documentPane = layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
            }

            _suspendLayoutItemCreation = true;
            foreach (var documentContentToImport in listOfDocumentsToImport)
            {
                var documentToImport = new LayoutDocument()
                {
                    Content = documentContentToImport
                };

                bool added = false;
                if (LayoutUpdateStrategy != null)
                {
                    added = LayoutUpdateStrategy.BeforeInsertDocument(layout, documentToImport, documentPane);
                }

                if (!added)
                {
                    if (documentPane == null)
                        throw new InvalidOperationException(
                            "Layout must contains at least one LayoutDocumentPane in order to host documents");

                    documentPane.Children.Add(documentToImport);
                }

                LayoutUpdateStrategy?.AfterInsertDocument(layout, documentToImport);

                CreateDocumentLayoutItem(documentToImport);
            }
            _suspendLayoutItemCreation = true;

            var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged;
            if (documentsSourceAsNotifier != null)
                documentsSourceAsNotifier.CollectionChanged += DocumentsSourceElementsChanged;
        }
        private void CreateDocumentLayoutItem(LayoutDocument contentToAttach)
        {
            if (_layoutItems.Any(item => Equals(item.LayoutElement, contentToAttach)))
                return;

            var layoutItem = new LayoutDocumentItem();
            layoutItem.Attach(contentToAttach);
            ApplyStyleToLayoutItem(layoutItem);
            _layoutItems.Add(layoutItem);

            if (contentToAttach?.Content is UIElement)
            {
                InternalAddLogicalChild(contentToAttach.Content);
            }
        }
        internal void _ExecuteCloseCommand(LayoutDocument document)
        {
            if (DocumentClosing != null)
            {
                var evargs = new DocumentClosingEventArgs(document);
                DocumentClosing(this, evargs);
                if (evargs.Cancel)
                    return;
            }

            if (!document.TestCanClose())
                return;

            document.Close();

            if (DocumentClosed != null)
            {
                var evargs = new DocumentClosedEventArgs(document);
                DocumentClosed(this, evargs);
            }
        }
 public override void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement)
 {
     Debug.Assert(Equals(oldElement, RootDocument) && oldElement != null);
     RootDocument = newElement as LayoutDocument;
 }
 public override void RemoveChild(ILayoutElement element)
 {
     Debug.Assert(Equals(element, RootDocument) && element != null);
     RootDocument = null;
 }
 public override void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement)
 {
     Debug.Assert(Equals(oldElement, RootDocument) && oldElement != null);
     RootDocument = newElement as LayoutDocument;
 }
 public override void RemoveChild(ILayoutElement element)
 {
     Debug.Assert(Equals(element, RootDocument) && element != null);
     RootDocument = null;
 }