Ejemplo n.º 1
0
        // NOTE:  This method is static, because the actual SplitTabsControl that created the view may not be the one in which
        // that view lives at the time it is closed.  Being static forces the method to use the sender to obtain the appropriate
        // parent control.
        static void OnViewClosed(object sender, EventArgs e)
        {
            View view = sender as View;

            if (view == null)
            {
                return;
            }

            ActivatableTabItem    item             = ActivatableTabItem.GetTabItem(view);
            ActivatableTabControl tabControl       = item.TabControlParent;
            SplitTabsControl      splitTabsControl = tabControl.FindParent <SplitTabsControl>();
            TabNode node        = tabControl.TabNode;
            bool    switchFocus = tabControl.IsKeyboardFocusWithin;

            splitTabsControl.RemoveItemFromControl(item);

            if (switchFocus)
            {
                if (node.TabControl.SelectedItem is ActivatableTabItem)
                {
                    ((ActivatableTabItem)node.TabControl.SelectedItem).Focus();
                }
                else if (node == splitTabsControl.activeTabNode)
                {
                    // We just closed the last view in the active node.  Need to switch the active
                    // tab node to the last active one.
                    splitTabsControl.ActivateLastActiveTabNode();
                }
            }

            view.Closed -= OnViewClosed;
        }
Ejemplo n.º 2
0
        ActivatableTabItem CreateTabItem(IViewCreationCommand viewCreator, IServiceProvider serviceProvider)
        {
            View view = viewCreator.CreateView(serviceProvider);

            view.Title = viewCreator.DisplayName;
            var item = new ActivatableTabItem()
            {
                ViewCreator = viewCreator,
                View        = view
            };

            ActivatableTabItem.SetTabItem(view, item);
            view.Site = item;
            item.SetBinding(ActivatableTabItem.ContentProperty, new Binding {
                Source = view, Path = new PropertyPath("ViewContent")
            });
            item.SetBinding(ActivatableTabItem.HeaderProperty, new Binding {
                Source = view, Path = new PropertyPath("Title")
            });
            AutomationProperties.SetAutomationId(item, viewCreator.RegisteredName);

            view.Closed += OnViewClosed;

            return(item);
        }
Ejemplo n.º 3
0
        public void NotifyActivation(object child)
        {
            var tabItem = child as ActivatableTabItem;

            if (tabItem != null)
            {
                this.lastActiveChildSite = tabItem;
                this.ParentSite.NotifyActivation(this);
            }
        }
Ejemplo n.º 4
0
        public void BubbleActivation(object child)
        {
            var tabItem = child as ActivatableTabItem;

            if (tabItem != null && this.Items.Contains(tabItem))
            {
                this.lastActiveChildSite = tabItem;
                this.SelectedIndex       = this.Items.IndexOf(tabItem);
                this.ParentSite.BubbleActivation(this);
            }
        }
Ejemplo n.º 5
0
        public ActivatableTabItem CreateView(IViewCreationCommand viewCreator, IServiceProvider serviceProvider, TabNode destinationNode = null)
        {
            ActivatableTabItem item = CreateTabItem(viewCreator, serviceProvider);

            if (destinationNode == null)
            {
                destinationNode = this.activeTabNode;
            }

            AddItemToControl(item, destinationNode.TabControl, true);
            return(item);
        }
Ejemplo n.º 6
0
        public void TunnelActivation()
        {
            if (this.lastActiveChildSite == null)
            {
                this.lastActiveChildSite = this.SelectedItem as ActivatableTabItem;
            }

            if (this.lastActiveChildSite != null)
            {
                this.lastActiveChildSite.TunnelActivation();
            }
        }
        private void OnMouseLeftButtonDown(ActivatableTabItem item, MouseButtonEventArgs e)
        {
            e.MouseDevice.Capture(item);

            this.draggedItem = item;
            this.sourceControl = item.FindParent<ActivatableTabControl>();
            this.sourceSplitTabsControl = this.sourceControl.FindParent<SplitTabsControl>();

            this.offset = e.GetPosition(item);
            this.preMoving = true;

            item.LostMouseCapture += this.OnLostMouseCapture;
            item.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
            item.MouseMove += this.OnMouseMove;
        }
        private void OnMouseLeftButtonDown(ActivatableTabItem item, MouseButtonEventArgs e)
        {
            e.MouseDevice.Capture(item);

            this.draggedItem            = item;
            this.sourceControl          = item.FindParent <ActivatableTabControl>();
            this.sourceSplitTabsControl = this.sourceControl.FindParent <SplitTabsControl>();

            this.offset    = e.GetPosition(item);
            this.preMoving = true;

            item.LostMouseCapture  += this.OnLostMouseCapture;
            item.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
            item.MouseMove         += this.OnMouseMove;
        }
Ejemplo n.º 9
0
        void OnTabClosed(object sender, RoutedEventArgs e)
        {
            ActivatableTabItem item = e.OriginalSource as ActivatableTabItem;

            if (item != null)
            {
                var view = item.View;

                if (view != null)
                {
                    // Note that "tab closed" is different than "view closed"
                    // This allows programmatic closing of a view by calling Close on the actual View
                    // object, and having it have the same effect as clicking the close box on a tab.
                    view.Close();
                }
            }
        }
Ejemplo n.º 10
0
        public void AddItemToControl(ActivatableTabItem item, ActivatableTabControl tabControl, bool giveFocus)
        {
            Debug.Assert(tabControl.FindParent <SplitTabsControl>() == this, "Can't add item to a tab control not owned by this split tabs control!");

            if (giveFocus)
            {
                RoutedEventHandler loadedHandler = null;

                loadedHandler = (s, e2) =>
                {
                    item.Focus();
                    item.Loaded -= loadedHandler;
                };
                item.Loaded += loadedHandler;
            }

            tabControl.ParentSite = this;
            tabControl.Items.Add(item);
        }
Ejemplo n.º 11
0
        XElement CreateTabElement(ActivatableTabItem item)
        {
            var element = new XElement("Tab",
                                       new XAttribute("RegisteredName", item.ViewCreator.RegisteredName),
                                       new XAttribute("IsSelected", item.IsSelected));

            var view = item.View;

            if (view != null)
            {
                var state = view.GetViewState();

                if (state != null)
                {
                    element.Add(new XElement("PrivateState", view.GetViewState()));
                }
            }

            return(element);
        }
Ejemplo n.º 12
0
        void OnTabActivated(object sender, RoutedEventArgs e)
        {
            ActivatableTabItem item = e.OriginalSource as ActivatableTabItem;

            if (item == null)
            {
                return;
            }

            if (item.View != null)
            {
                item.View.HandleActivation();
            }

            TabNode node = item.TabControlParent.TabNode;

            if (node != null)
            {
                ActivateTabNode(node);
            }
        }
 public static void SetTabItem(DependencyObject obj, ActivatableTabItem value)
 {
     obj.SetValue(TabItemProperty, value);
 }
        XElement CreateTabElement(ActivatableTabItem item)
        {
            var element = new XElement("Tab",
                new XAttribute("RegisteredName", item.ViewCreator.RegisteredName),
                new XAttribute("IsSelected", item.IsSelected));

            var view = item.View;

            if (view != null)
            {
                var state = view.GetViewState();

                if (state != null)
                {
                    element.Add(new XElement("PrivateState", view.GetViewState()));
                }
            }

            return element;
        }
        ActivatableTabItem CreateTabItem(IViewCreationCommand viewCreator, IServiceProvider serviceProvider)
        {
            View view = viewCreator.CreateView(serviceProvider);

            view.Title = viewCreator.DisplayName;
            var item = new ActivatableTabItem()
            {
                ViewCreator = viewCreator,
                View = view
            };

            ActivatableTabItem.SetTabItem(view, item);
            view.Site = item;
            item.SetBinding(ActivatableTabItem.ContentProperty, new Binding { Source = view, Path = new PropertyPath("ViewContent") });
            item.SetBinding(ActivatableTabItem.HeaderProperty, new Binding { Source = view, Path = new PropertyPath("Title") });
            AutomationProperties.SetAutomationId(item, viewCreator.RegisteredName);

            view.Closed += OnViewClosed;

            return item;
        }
Ejemplo n.º 16
0
        public void RemoveItemFromControl(ActivatableTabItem item)
        {
            var control = item.FindParent <ActivatableTabControl>();

            if (control == null)
            {
                Debug.Fail("Can't find parent tab control!");
                return;
            }

            var node = control.TabNode;

            if (node == null)
            {
                Debug.Fail("Tab control does not have a tab node set!");
                return;
            }

            node.TabControl.Items.Remove(item);
            if (node.TabControl.Items.Count == 0)
            {
                bool wasActive = (node == this.activeTabNode);

                // No more tabs in this control.
                if (node.Parent != null)
                {
                    // This node is no longer needed.  Remove the tab control and fix the tree.
                    this.host.Children.Remove(node.TabControl);

                    node.Parent.Children.Remove(node);
                    node.Parent.Slot.Children.Remove(node.Slot);

                    TabNode lastChild = node.Parent.Children[0];

                    if (node.Parent.Children.Count == 1)
                    {
                        // The parent now only has a single child. That means the last node (lastChild) is no longer
                        // necessary; its contents should collapse up into the parent. Note that this could "bleed up"
                        // into the grandparent, as in this case:
                        //
                        // ------------------------
                        // |      |   |   |       |
                        // |      |   |   |       |
                        // |      |   |   |       |
                        // |      |-------|       |
                        // |      |       |       |
                        // |      |   X   |       |
                        // |      |       |       |
                        // ------------------------
                        //
                        // Closing the X node leaves a single node in its parent, so that node replaces the parent.
                        // That node contains two children, and has horizontal orientation like it's *new* parent
                        // (the grandparent).  In these cases, the parent node also becomes unnecessary, and should
                        // be replaced in the grandparent node with all of its children.
                        //
                        // Note that programmatically, it is possible to create a node tree such that node has children
                        // (with grandchildren) that have the same orientation as the parent.  However, using the drag
                        // manager, this should never happen; the logic in SplitNode detects such cases and inserts
                        // nodes appropriately such that orientation always flips as you go down the tree.  So, any time
                        // the remaining child (lastChild) has children, it should always result in this "bleed up"
                        // effect. But we check just in case.
                        if (lastChild.Children != null)
                        {
                            var grandparent = node.Parent.Parent;

                            if (grandparent != null && lastChild.Slot.Orientation == grandparent.Slot.Orientation)
                            {
                                // Here's the "bleed up" -- skip right past parent
                                int    index = grandparent.Children.IndexOf(node.Parent);
                                double totalSizeInLastChild   = lastChild.Slot.Children.Sum(s => s.Length.Value);
                                double totalSizeInGrandParent = grandparent.Slot.Children.Sum(s => s.Length.Value);

                                grandparent.Children.RemoveAt(index);
                                grandparent.Slot.Children.RemoveAt(index);
                                foreach (var child in lastChild.Children)
                                {
                                    grandparent.Children.Insert(index, child);
                                    child.Parent = grandparent;
                                    grandparent.Slot.Children.Insert(index, child.Slot);
                                    child.Slot.Length = new GridLength((child.Slot.Length.Value / totalSizeInLastChild) * totalSizeInGrandParent, GridUnitType.Star);
                                    index            += 1;
                                }
                            }
                            else
                            {
                                // Just put lastChild's children into the parent, replacing itself.  This case should only
                                // get hit if the parent is the root, unless someone does programmatic manipulation of the slots.
                                node.Parent.Children.Clear();
                                node.Parent.Slot.Children.Clear();
                                foreach (var child in lastChild.Children)
                                {
                                    node.Parent.Children.Add(child);
                                    child.Parent = node.Parent;
                                    node.Parent.Slot.Children.Add(child.Slot);
                                }
                                node.Parent.Slot.Orientation = lastChild.Slot.Orientation;
                            }
                        }
                        else
                        {
                            // Just put lastChild's tab control into the parent, removing itself
                            node.Parent.Children = null;
                            node.Parent.Slot.Children.Clear();
                            node.Parent.TabControl = lastChild.TabControl;
                            SlotPanel.SetSlotName(node.Parent.TabControl, node.Parent.Slot.Name);
                            node.Parent.TabControl.TabNode = node.Parent;
                        }
                    }

                    if (wasActive)
                    {
                        ActivateLastActiveTabNode();
                    }
                }
                else
                {
                    // We're now empty, completely.  If we're a floating host, go away.
                    if (this.masterControl != null)
                    {
                        var parent = this.FindParent <FloatingWindow>();

                        if (parent != null)
                        {
                            parent.Close();
                        }
                    }
                }
            }
        }
        public void RemoveItemFromControl(ActivatableTabItem item)
        {
            var control = item.FindParent<ActivatableTabControl>();

            if (control == null)
            {
                Debug.Fail("Can't find parent tab control!");
                return;
            }

            var node = control.TabNode;

            if (node == null)
            {
                Debug.Fail("Tab control does not have a tab node set!");
                return;
            }

            node.TabControl.Items.Remove(item);
            if (node.TabControl.Items.Count == 0)
            {
                bool wasActive = (node == this.activeTabNode);

                // No more tabs in this control.
                if (node.Parent != null)
                {
                    // This node is no longer needed.  Remove the tab control and fix the tree.
                    this.host.Children.Remove(node.TabControl);

                    node.Parent.Children.Remove(node);
                    node.Parent.Slot.Children.Remove(node.Slot);

                    TabNode lastChild = node.Parent.Children[0];

                    if (node.Parent.Children.Count == 1)
                    {
                        // The parent now only has a single child. That means the last node (lastChild) is no longer
                        // necessary; its contents should collapse up into the parent. Note that this could "bleed up"
                        // into the grandparent, as in this case:
                        //
                        // ------------------------
                        // |      |   |   |       |
                        // |      |   |   |       |
                        // |      |   |   |       |
                        // |      |-------|       |
                        // |      |       |       |
                        // |      |   X   |       |
                        // |      |       |       |
                        // ------------------------
                        // 
                        // Closing the X node leaves a single node in its parent, so that node replaces the parent.
                        // That node contains two children, and has horizontal orientation like it's *new* parent
                        // (the grandparent).  In these cases, the parent node also becomes unnecessary, and should 
                        // be replaced in the grandparent node with all of its children.
                        //
                        // Note that programmatically, it is possible to create a node tree such that node has children
                        // (with grandchildren) that have the same orientation as the parent.  However, using the drag
                        // manager, this should never happen; the logic in SplitNode detects such cases and inserts
                        // nodes appropriately such that orientation always flips as you go down the tree.  So, any time
                        // the remaining child (lastChild) has children, it should always result in this "bleed up"
                        // effect. But we check just in case.
                        if (lastChild.Children != null)
                        {
                            var grandparent = node.Parent.Parent;

                            if (grandparent != null && lastChild.Slot.Orientation == grandparent.Slot.Orientation)
                            {
                                // Here's the "bleed up" -- skip right past parent
                                int index = grandparent.Children.IndexOf(node.Parent);
                                double totalSizeInLastChild = lastChild.Slot.Children.Sum(s => s.Length.Value);
                                double totalSizeInGrandParent = grandparent.Slot.Children.Sum(s => s.Length.Value);

                                grandparent.Children.RemoveAt(index);
                                grandparent.Slot.Children.RemoveAt(index);
                                foreach (var child in lastChild.Children)
                                {
                                    grandparent.Children.Insert(index, child);
                                    child.Parent = grandparent;
                                    grandparent.Slot.Children.Insert(index, child.Slot);
                                    child.Slot.Length = new GridLength((child.Slot.Length.Value / totalSizeInLastChild) * totalSizeInGrandParent, GridUnitType.Star);
                                    index += 1;
                                }
                            }
                            else
                            {
                                // Just put lastChild's children into the parent, replacing itself.  This case should only
                                // get hit if the parent is the root, unless someone does programmatic manipulation of the slots.
                                node.Parent.Children.Clear();
                                node.Parent.Slot.Children.Clear();
                                foreach (var child in lastChild.Children)
                                {
                                    node.Parent.Children.Add(child);
                                    child.Parent = node.Parent;
                                    node.Parent.Slot.Children.Add(child.Slot);
                                }
                                node.Parent.Slot.Orientation = lastChild.Slot.Orientation;
                            }
                        }
                        else
                        {
                            // Just put lastChild's tab control into the parent, removing itself
                            node.Parent.Children = null;
                            node.Parent.Slot.Children.Clear();
                            node.Parent.TabControl = lastChild.TabControl;
                            SlotPanel.SetSlotName(node.Parent.TabControl, node.Parent.Slot.Name);
                            node.Parent.TabControl.TabNode = node.Parent;
                        }
                    }

                    if (wasActive)
                    {
                        ActivateLastActiveTabNode();
                    }
                }
                else
                {
                    // We're now empty, completely.  If we're a floating host, go away.
                    if (this.masterControl != null)
                    {
                        var parent = this.FindParent<FloatingWindow>();

                        if (parent != null)
                            parent.Close();
                    }
                }
            }
        }
        public void TunnelActivation()
        {
            if (this.lastActiveChildSite == null)
            {
                this.lastActiveChildSite = this.SelectedItem as ActivatableTabItem;
            }

            if (this.lastActiveChildSite != null)
            {
                this.lastActiveChildSite.TunnelActivation();
            }
        }
Ejemplo n.º 19
0
        TabNode LoadTabNode(XElement nodeElement, IDictionary <string, IViewCreationCommand> viewCreators, IServiceProvider serviceProvider)
        {
            XElement children = nodeElement.Element("Children");
            TabNode  node     = new TabNode {
                Slot = new Slot {
                    Name = GetNextSlotName()
                }
            };

            if (children != null)
            {
                node.Slot.Orientation = (Orientation)Enum.Parse(typeof(Orientation), nodeElement.Attribute("Orientation").Value);
                node.Children         = new List <TabNode>();

                foreach (var childElement in children.Elements("TabNode"))
                {
                    TabNode childNode = LoadTabNode(childElement, viewCreators, serviceProvider);
                    double  size      = double.Parse(childElement.Attribute("Length").Value, CultureInfo.InvariantCulture);

                    childNode.Slot.Length = new GridLength(size, GridUnitType.Star);
                    childNode.Parent      = node;
                    node.Children.Add(childNode);
                    node.Slot.Children.Add(childNode.Slot);
                }
            }
            else
            {
                XElement tabs     = nodeElement.Element("Tabs");
                bool     isActive = bool.Parse(nodeElement.Attribute("IsActive").Value);

                node.TabControl = new ActivatableTabControl();
                SlotPanel.SetSlotName(node.TabControl, node.Slot.Name);
                node.TabControl.TabNode = node;

                foreach (var tab in tabs.Elements("Tab"))
                {
                    string registeredName = tab.Attribute("RegisteredName").Value;
                    bool   isSelected     = bool.Parse(tab.Attribute("IsSelected").Value);
                    IViewCreationCommand creator;

                    if (!viewCreators.TryGetValue(registeredName, out creator))
                    {
                        // If the view is bogus, just skip it.
                        continue;
                    }

                    ActivatableTabItem item         = CreateTabItem(creator, serviceProvider);
                    XElement           privateState = tab.Element("PrivateState");

                    if (privateState != null && privateState.HasElements)
                    {
                        item.View.LoadViewState(privateState.Elements().First());
                    }

                    node.TabControl.Items.Add(item);
                    if (isSelected)
                    {
                        node.TabControl.SelectedItem = item;
                        if (isActive)
                        {
                            this.activeTabNode       = node;
                            node.TabControl.IsActive = true;
                        }
                    }
                }
            }

            return(node);
        }
 public static void BeginDrag(ActivatableTabItem item, MouseButtonEventArgs e)
 {
     new TabItemDragManager().OnMouseLeftButtonDown(item, e);
 }
        public void NotifyActivation(object child)
        {
            var tabItem = child as ActivatableTabItem;

            if (tabItem != null)
            {
                this.lastActiveChildSite = tabItem;
                this.ParentSite.NotifyActivation(this);
            }
        }
        public void BubbleActivation(object child)
        {
            var tabItem = child as ActivatableTabItem;

            if (tabItem != null && this.Items.Contains(tabItem))
            {
                this.lastActiveChildSite = tabItem;
                this.SelectedIndex = this.Items.IndexOf(tabItem);
                this.ParentSite.BubbleActivation(this);
            }
        }
        public void AddItemToControl(ActivatableTabItem item, ActivatableTabControl tabControl, bool giveFocus)
        {
            Debug.Assert(tabControl.FindParent<SplitTabsControl>() == this, "Can't add item to a tab control not owned by this split tabs control!");

            if (giveFocus)
            {
                RoutedEventHandler loadedHandler = null;

                loadedHandler = (s, e2) =>
                {
                    item.Focus();
                    item.Loaded -= loadedHandler;
                };
                item.Loaded += loadedHandler;
            }

            tabControl.ParentSite = this;
            tabControl.Items.Add(item);
        }
 public static void SetTabItem(DependencyObject obj, ActivatableTabItem value)
 {
     obj.SetValue(TabItemProperty, value);
 }
 public static void BeginDrag(ActivatableTabItem item, MouseButtonEventArgs e)
 {
     new TabItemDragManager().OnMouseLeftButtonDown(item, e);
 }