Question

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
Was it helpful?

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();
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top