ribbonribboncontrolslibrary

Save/ load QuickAccessToolBar


I 'm using Microsoft.Windows.Controls.Ribbon, and i would like save and load QuickAccessToolBar.

How I Can find QuickAccessToolBar items, in ribbon control?

This is my idea to save ribbon QuickAccessToolBar

  1. OnClosing application : Get QuickAccessToolBar items, and locaize on Ribbon items. And then serialize
  2. OnLoad : Read serilize object, and add insert items QuickAccessToolBar

Solution

  • Finally i did it!

    I'm based on WPF Ribbon Sample to save/load. It used datacontext to localize control on RibbonControl, and i didn't like, so i isued QuickAccessToolBarId to localize the control.

    This is the solution: - OnClosing Application: I save QuickAccessToolBar, search items on ribbon control by QuickAccessToolBar, and save path. Note: When item is in application menufirst path is -1.A - OnLoadApplication:

    Load items , and seerch on ribbon control by path.

    And this is the code:

    RibbonHelper:

      class RibbonHelper
        {
            Ribbon ribbon;
            public RibbonHelper(Ribbon ribbon)
            {
                this.ribbon = ribbon;
    
            }
            string _qatFileName = "qat.xml";
    
    
            internal void Save()
            {
                try
                {
                    SaveQatItems();
                }
                catch { }
    
    
            }
    
    
    
    
            internal void Load()
            {
                try
                {
                    LoadQatItems();
                }
                catch
                {
                }
            }
    
    
            #region Save Qat
    
            private void SaveQatItems()
            {
    
    
               QatItemCollection qatItems = GetQatItemsToSave(ribbon.QuickAccessToolBar);
    
               if (qatItems != null)
               {
    
                   QatItemCollection remainingItems = new QatItemCollection();
                   remainingItems.AddRange(qatItems);
                   SaveQatItemsOfApplicationMenu(remainingItems);
                   SaveQatItemsOfTabs(remainingItems);
    
                   SaveQatItems(qatItems);
    
    
               }
    
            }
    
            private void SaveQatItems(QatItemCollection qatItems)
            {
                XmlWriter xmlWriter = XmlWriter.Create(_qatFileName);
                XamlWriter.Save(qatItems, xmlWriter);
                xmlWriter.Close();
            }
    
            private void SaveQatItemsOfApplicationMenu(QatItemCollection remainingItems)
            {
                if (ribbon.ApplicationMenu != null)
                {
                    if (remainingItems != null)
                    {
                        remainingItems.ForEach(qat =>
                        {
                            qat.ControlIndices.Add(-1);
                        });
                        for (int index = 0; index < ribbon.ApplicationMenu.Items.Count && remainingItems.Count > 0; index++)
                        {
                            SaveQatItemsAmongChildren(remainingItems, ribbon.ApplicationMenu.Items[index],index);
                        }
                        remainingItems.ForEach(qat =>
                        {
    
                            qat.ControlIndices.Clear();
                        });
                    }
                }
            }
    
            private void SaveQatItemsOfTabs(QatItemCollection remainingItems)
            {
                if (ribbon.Items != null)
                {
                    if (remainingItems != null)
                    {
                        for (int tabIndex = 0; tabIndex < ribbon.Items.Count && remainingItems.Count > 0; tabIndex++)
                        {
                            RibbonTab tab = ribbon.Items[tabIndex] as RibbonTab;
                            SaveQatItemsAmongChildren(remainingItems, tab, tabIndex);
    
                        }
    
                    }
                }
            }
    
            private void SaveQatItemsAmongChildren(QatItemCollection remainingItems, object control, int controlIndex)
            {
                if (control == null)
                {
                    return;
                }
    
                //AƱaidmos el control index a los pendientes
                remainingItems.ForEach(qat =>
                {
                    qat.ControlIndices.Add(controlIndex);
                });
    
                SaveQatItemsAmongChildrenInner(remainingItems, control);
    
                //Eliminamos el control index de los pendientes ya que no estan dentro de ese control
                remainingItems.ForEach(qat =>
               {
                   int last = qat.ControlIndices.Count - 1;
                   qat.ControlIndices.RemoveAt(last);
               });
    
            }
    
            private void SaveQatItemsAmongChildrenInner(QatItemCollection remainingItems, object parent)
            {
                SaveQatItemsIfMatchesControl(remainingItems, parent);
    
                if (remainingItems.Count == 0 || IsLeaf(parent))
                {
                    return;
                }            
    
                int childIndex = 0;
                DependencyObject dependencyObject = parent as DependencyObject;
                if (dependencyObject != null)
                {
                    IEnumerable children = LogicalTreeHelper.GetChildren(dependencyObject);
                    foreach (object child in children)
                    {
                        SaveQatItemsAmongChildren(remainingItems, child, childIndex);
                        childIndex++;
                    }
                }
                if (childIndex != 0)
                {
                    return;
                }
    
                // if we failed to get any logical children, enumerate the visual ones
                Visual visual = parent as Visual;
                if (visual == null)
                {
                    return;
                }
                for (childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(visual); childIndex++)
                {
                    Visual child = VisualTreeHelper.GetChild(visual, childIndex) as Visual;
                    SaveQatItemsAmongChildren(remainingItems, child, childIndex);
                }
    
            }
    
            private bool IsLeaf(object element)
            {
                if ((element is RibbonButton) ||
                (element is RibbonToggleButton) ||
                (element is RibbonRadioButton) ||
                (element is RibbonCheckBox) ||
                (element is RibbonTextBox) ||
                (element is RibbonSeparator))
                {
                    return true;
                }
    
                RibbonMenuItem menuItem = element as RibbonMenuItem;
                if (menuItem != null &&
                    menuItem.Items.Count == 0)
                {
                    return true;
                }
    
                return false;
            }
    
            private bool SaveQatItemsIfMatchesControl(QatItemCollection remainingItems, object control)
            {
                bool matched = false;
                FrameworkElement element = control as FrameworkElement;
                if (element != null)
                {
                    object getQuickAccessToolBarId = RibbonControlService.GetQuickAccessToolBarId(element);
                    if (getQuickAccessToolBarId != null)
                    {
                        int remove = remainingItems.RemoveAll(qat => qat.QuickAccessToolBarIdHashCode == getQuickAccessToolBarId.GetHashCode());
                        matched = remove > 0;
                    }
                }
    
                return matched;
            }
    
            private  QatItemCollection GetQatItemsToSave(RibbonQuickAccessToolBar qat)
            {
                QatItemCollection qatItems = new QatItemCollection();
                if (qat != null && qat.Items != null && qat.Items.Count > 0)
                {
                    foreach (var item in qat.Items)
                    {
    
                        FrameworkElement element = item as FrameworkElement;
    
                        if (element != null)
                        {
                            object getQuickAccessToolBarId = RibbonControlService.GetQuickAccessToolBarId(element);
                            if (getQuickAccessToolBarId != null)
                            {
    
                                QatItem qatItem = new QatItem(getQuickAccessToolBarId.GetHashCode());
                                qatItems.Add(qatItem);
    
                            }
                        }
    
    
    
                    }
                }
                return qatItems;
            }
            #endregion
    
            #region load qat
            private void LoadQatItems()
            {
                if (ribbon.QuickAccessToolBar == null)
                {
                    ribbon.QuickAccessToolBar = new RibbonQuickAccessToolBar();
                }
                QatItemCollection qatItems = GetQatItemsToLoad();
                if ((qatItems != null) && (qatItems.Count > 0))
                {
    
                    SearchInApplicationMenu(qatItems);
                    SearchInTabs(qatItems);
    
    
    
    
                    qatItems.Where(qat => qat.Owner != null).ToList().ForEach(qat =>
                    {
                        if (RibbonCommands.AddToQuickAccessToolBarCommand.CanExecute(null, qat.Owner))
                        {
                            RibbonCommands.AddToQuickAccessToolBarCommand.Execute(null, qat.Owner);
                        }
                    });
    
                }
    
    
    
            }
    
            private void SearchInApplicationMenu(QatItemCollection qatItems)
            {
                if (qatItems != null)
                {
    
                    int remainingItemsCount = qatItems.Count(qat=>qat.Owner==null);
                    QatItemCollection matchedItems = new QatItemCollection();
    
                    for (int index = 0; index < ribbon.ApplicationMenu.Items.Count && remainingItemsCount > 0; index++)
                    {
                        matchedItems.Clear();
                        matchedItems.AddRange(qatItems.Where(qat => qat.ControlIndices[0] == -1)); //-1 is applicationMenu
    
                        //remove -1
                        matchedItems.ForEach(qat =>
                        {
                            qat.ControlIndices.RemoveAt(0);
                        }
                       );
    
    
                        object item = ribbon.ApplicationMenu.Items[index];
                        if (item != null)
                        {
    
                            if (!IsLeaf(item))
                            {
                                LoadQatItemsAmongChildren(matchedItems, 0, index, item, ref remainingItemsCount);
                            }
                            else
                            {
    
                                LoadQatItemIfMatchesControl(matchedItems, new QatItemCollection(), 0, index, item, ref remainingItemsCount);
                            }
                        }
                        //Add -1
                        matchedItems.ForEach(qat =>
                       {
                           qat.ControlIndices.Insert(0, -1);
                       });
    
                    }
                }
    
            }
    
            private void SearchInTabs(QatItemCollection qatItems)
            {
    
                int remainingItemsCount = qatItems.Count(qat => qat.Owner == null);
                QatItemCollection matchedItems = new QatItemCollection();
    
    
                for (int tabIndex = 0; tabIndex < ribbon.Items.Count && remainingItemsCount > 0; tabIndex++)
                {
                    matchedItems.Clear();
                    matchedItems.AddRange(qatItems.Where(qat => qat.ControlIndices[0] == tabIndex)); 
    
                    RibbonTab tab = ribbon.Items[tabIndex] as RibbonTab;
                    if (tab != null)
                    {
                        LoadQatItemsAmongChildren(matchedItems, 0, tabIndex, tab, ref remainingItemsCount);
                    }
                }
            }
    
    
            private void LoadQatItemsAmongChildren(
                        QatItemCollection previouslyMatchedItems,
                        int matchLevel,
                        int controlIndex,
                        object parent,
                        ref int remainingItemsCount)
            {
                if (previouslyMatchedItems.Count == 0)
                {
                    return;
                }
                if (IsLeaf(parent))
                {
                    return;
                }
    
                int childIndex = 0;
                DependencyObject dependencyObject = parent as DependencyObject;
                if (dependencyObject != null)
                {
                    IEnumerable children = LogicalTreeHelper.GetChildren(dependencyObject);
                    foreach (object child in children)
                    {
                        if (remainingItemsCount == 0)
                        {
                            break;
                        }
    
                        QatItemCollection matchedItems = new QatItemCollection();
                        LoadQatItemIfMatchesControl(previouslyMatchedItems, matchedItems, matchLevel + 1, childIndex, child, ref remainingItemsCount);
                        LoadQatItemsAmongChildren(matchedItems, matchLevel + 1, childIndex, child, ref remainingItemsCount);
                        childIndex++;
                    }
                }
                if (childIndex != 0)
                {
                    return;
                }
    
                // if we failed to get any logical children, enumerate the visual ones
                Visual visual = parent as Visual;
                if (visual == null)
                {
                    return;
                }
                for (childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(visual); childIndex++)
                {
                    if (remainingItemsCount == 0)
                    {
                        break;
                    }
    
                    Visual child = VisualTreeHelper.GetChild(visual, childIndex) as Visual;
                    QatItemCollection matchedItems = new QatItemCollection();
                    LoadQatItemIfMatchesControl(previouslyMatchedItems, matchedItems, matchLevel + 1, childIndex, child, ref remainingItemsCount);
                    LoadQatItemsAmongChildren(matchedItems, matchLevel + 1, childIndex, child, ref remainingItemsCount);
                }
            }
    
    
            private void LoadQatItemIfMatchesControl(
                     QatItemCollection previouslyMatchedItems,
                     QatItemCollection matchedItems,
                     int matchLevel,
                     int controlIndex,
                     object control,
                     ref int remainingItemsCount)
            {
                for (int qatIndex = 0; qatIndex < previouslyMatchedItems.Count; qatIndex++)
                {
                    QatItem qatItem = previouslyMatchedItems[qatIndex];
                    if (qatItem.ControlIndices[matchLevel] == controlIndex)
                    {
                        if (qatItem.ControlIndices.Count == matchLevel + 1)
                        {
                            qatItem.Owner = control as Control; ;
                            remainingItemsCount--;
                        }
    
                        else
                        {
                            matchedItems.Add(qatItem);
                        }
                    }
                }
            }
    
    
    
            private QatItemCollection GetQatItemsToLoad()
            {
                try
                {
                    if (File.Exists(_qatFileName))
                    {
    
                        using (XmlReader xmlReader = XmlReader.Create(_qatFileName))
                        {
                            QatItemCollection qatItems = (QatItemCollection)XamlReader.Load(xmlReader);
                            xmlReader.Close();
                            return qatItems;
                        }
                    }
                }
                catch
                {
                    //Do nothing, return null;
                }
    
                return null;
            }
            #endregion
        }
    

    Classes to serialize:

              public class QatItem    {
            public QatItem()
            {
    
            }
    
            public QatItem(int qatbIdHashCode)
            {
                QuickAccessToolBarIdHashCode = qatbIdHashCode;
    
            }
    
    
    
            public Int32Collection ControlIndices
            {
                get
                {
                    if (_controlIndices == null)
                    {
                        _controlIndices = new Int32Collection();
                    }
                    return _controlIndices;
                }
                set
                {
                    _controlIndices = value;
                }
            }
            Int32Collection _controlIndices;
    
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            public int QuickAccessToolBarIdHashCode { get; set; }
    
            //Is only for load
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            public Control Owner { get; set; }
    
    
        }
      public class QatItemCollection : List<QatItem>
        {
        }
    

    And this is the code to save/load from window

     RibbonHelper helper;
            protected override void OnClosing(CancelEventArgs e)
            {
                helper.Save();
                base.OnClosing(e);
    
            }
    
            private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
            {
                helper = new RibbonHelper(ribbon);
                helper.Load();
            }