Recent Folders functionality using RadSplitButton

Thread is closed for posting
2 posts, 0 answers
  1. 311E1358-6E09-47B2-BF8D-1EF6A5CC130A
    311E1358-6E09-47B2-BF8D-1EF6A5CC130A avatar
    1 posts
    Member since:
    Feb 2016

    Posted 05 May 2016 Link to this post

    Requirements

    Telerik Product and Version

    UI for WinForms Q1 2016

    Supported Browsers and Platforms


    Components/Widgets used (JS frameworks, etc.)



    PROJECT DESCRIPTION 
    This project demonstrates the Recent Folders functionality (like Most Recently Used 'MRU') found in many commercial applications.

    Requirements

    SharpConfig library by Cemalettin Dervis

     

    Features

    • The folder history can be persisted to configuration file
    • Option to clear history
    • Option to remove folder item if it is not exist

    Class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Windows.Forms;
    using SharpConfig;
    using Telerik.WinControls.UI;
     
    namespace Recent
    {
        public class RecentFolders
        {
            readonly RadSplitButtonElement _param_Button;
            readonly string _param_FileName;
            readonly string _param_SectionName;
            readonly int _param_MaxDisplayItems;
     
            public readonly FolderBrowserDialog Dialog;
     
            List<string> _items;
     
            public event EventHandler<RecentFolderChangingEventArgs> RecentFolderChanging;
            public event EventHandler<RecentFolderChangedEventArgs> RecentFolderChanged;
     
            /// <summary>
            ///
            /// </summary>
            /// <param name="form"></param>
            /// <param name="button">For RadSplitButton, use DropDownButtonElement</param>
            /// <param name="fileName"></param>
            /// <param name="sectionName"></param>
            /// <param name="maxDisplayItems"></param>
            public RecentFolders(Form form, RadSplitButtonElement button, string fileName, string sectionName = "Recent", int maxDisplayItems = 10)
            {
                _param_Button = button;
                _param_FileName = fileName;
                _param_SectionName = sectionName;
                _param_MaxDisplayItems = maxDisplayItems;
     
                form.FormClosed +=
                    (sender, e) => Save();
     
                var browse = new RadMenuItem();
     
                browse.Click +=
                    (sender, e) => OnBrowseClick();
     
                _param_Button.DefaultItem = browse;
     
                _items = new List<string>();
     
                Dialog = new FolderBrowserDialog();
                Dialog.ShowNewFolderButton = false;
     
                Load();
            }
     
            void Load()
            {
                if (File.Exists(_param_FileName))
                {
                    try
                    {
                        Configuration cfg = Configuration.LoadFromFile(_param_FileName);
     
                        if (cfg.Contains(_param_SectionName))
                        {
                            foreach (var setting in cfg[_param_SectionName])
                                _items.Add(setting.StringValue);
     
                            if (_items.Count != 0)
                            {
                                Dialog.SelectedPath = _items[0];
                            }
                        }
                    }
                    catch
                    {
                    }
                }
     
                UpdateUI();
            }
     
            void Save()
            {
                Configuration cfg = null;
     
                if (File.Exists(_param_FileName))
                {
                    try
                    {
                        cfg = Configuration.LoadFromFile(_param_FileName);
     
                        if (cfg.Contains(_param_SectionName))
                            cfg.Remove(_param_SectionName);
                    }
                    catch
                    {
                    }
                }
     
                if (cfg == null)
                    cfg = new Configuration();
     
                var section = new Section(_param_SectionName);
     
                for (int i = 0; i < _items.Count; i++)
                {
                    section.Add(new Setting((i + 1).ToString(), _items[i]));
                }
     
                cfg.Add(section);
                cfg.SaveToFile(_param_FileName);
            }
     
            void UpdateUI()
            {
                _param_Button.Items.Clear();
     
                if (_items.Count != 0)
                {
                    int count =
                        _items.Count > _param_MaxDisplayItems ?
                            _param_MaxDisplayItems :
                            _items.Count;
     
                    for (int i = 0; i < count; i++)
                    {
                        var item = new RadMenuItem(_items[i]);
     
                        item.Click +=
                            (sender, e) => OnItemClick(((RadMenuItem)sender).Text);
     
                        _param_Button.Items.Add(item);
                    }
     
                    _param_Button.Items.Add(new RadMenuSeparatorItem());
     
                    var clear = new RadMenuItem("Clear Recent List");
     
                    clear.Click +=
                        (sender, e) => OnClearClick();
     
                    _param_Button.Items.Add(clear);
     
                    _param_Button.ArrowButton.Enabled = true;
                }
                else
                {
                    // Telerik Issue: If RadSplitButton is placed on RadForm, then this is not working.
                    _param_Button.ArrowButton.Enabled = false;
                }
            }
     
            void OnBrowseClick()
            {
                if (Continue())
                {
                    if (Dialog.ShowDialog() == DialogResult.OK)
                    {
                        AddToTop(Dialog.SelectedPath);
                    }
                }
            }
     
            void OnItemClick(string path)
            {
                if (Continue())
                {
                    if (Directory.Exists(path))
                    {
                        AddToTop(path);
                        Dialog.SelectedPath = path;
                    }
                    else
                    {
                        string s = string.Format("The folder '{0}' cannot be opened.\n\nDo you want to remove the reference to it from the Recent List?", path);
     
                        if (MessageBox.Show(s, "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            _items.Remove(path);
                            UpdateUI();
                        }
     
                        if (_items.Count != 0)
                            _param_Button.ShowDropDown();
                    }
                }
            }
     
            bool Continue()
            {
                if (RecentFolderChanging != null)
                {
                    var args = new RecentFolderChangingEventArgs();
                    RecentFolderChanging.Invoke(this, args);
     
                    return !args.Cancel;
                }
     
                return true;
            }
     
            void OnClearClick()
            {
                _items =
                    _items
                        .Skip(_param_MaxDisplayItems)
                        .ToList();
     
                UpdateUI();
     
                if (_items.Count != 0)
                    _param_Button.ShowDropDown();
            }
     
            void AddToTop(string path)
            {
                int index = _items.FindIndex(s => s.Equals(path, StringComparison.OrdinalIgnoreCase));
                if (index != 0)
                {
                    // Exist?
                    if (index != -1)
                        _items.RemoveAt(index);
     
                    _items.Insert(0, path);
     
                    UpdateUI();
                }
     
                if (RecentFolderChanged != null)
                {
                    RecentFolderChanged.Invoke(this, new RecentFolderChangedEventArgs(path));
                }
            }
        }
     
        public class RecentFolderChangingEventArgs : CancelEventArgs
        {
            public RecentFolderChangingEventArgs(bool cancel = false)
                : base(cancel)
            {
            }
        }
     
        public class RecentFolderChangedEventArgs : EventArgs
        {
            public string Path { get; private set; }
     
            public RecentFolderChangedEventArgs(string path)
            {
                Path = path;
            }
        }
    }

     

    To use, Add RadSplitButton or RadSplitButtonElement in RadForm or RadRibbonForm respectively and use following code...

    recent = new RecentFolders(this, btnOpen_Case_Home, AppSetting.FileName, AppSetting.RecentCases);
    recent.RecentFolderChanging += recent_RecentFolderChanging;
    recent.RecentFolderChanged += recent_RecentFolderChanged;

     

    Where...

    btnOpen_Case_Home = RadSplitButtonElement name

    AppSetting.FileName = Configuration filename to load/save folder history

    AppSetting.RecentCases = Section name to store folder history

     

    NOTE:

    • There is one more argument to RecentFolders constructor, to specify how many items must be displayed in dropdown.
    • The RecentFolders class exposes FolderDialog instance to customize it

    Please post suggestions or queries.

     

    Thanks

  2. 20136D5D-ACB5-439D-8CA0-3741B20FB7E4
    20136D5D-ACB5-439D-8CA0-3741B20FB7E4 avatar
    4180 posts
    Member since:
    Apr 2022

    Posted 09 May 2016 Link to this post

    Hello Ketan,

    Thank you for writing.

    Thank you for posting this code library article. 

    Your Telerik points have been updated for the community effort.

    Regards,
    Dess
    Telerik
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Back to Top

This Code Library is part of the product documentation and subject to the respective product license agreement.