Possible RadBrowseEditor Issue?

3 posts, 1 answers
  1. Santosh
    Santosh avatar
    2 posts
    Member since:
    Jan 2017

    Posted 19 Jan 2017 Link to this post

    Hello,

    Can someone tell me if it's possible to automatically scroll the selected folder in RadBrowserEditor into view? Currently, I am setting the 'value' property of this control to a folder that's is not part of the default view. When the dialog opens, the folder is selected as expected but it's not scrolled into view. So, I have to manually scroll in order to find the selected folder.

    Thanks,

    Santosh

  2. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    4077 posts

    Posted 20 Jan 2017 Link to this post

    Hello Santosh,

    Thank you for writing.  

    RadBrowseEditor uses the MS FolderBrowserDialog when the DialogType property is set to BrowseEditorDialogType.FolderBrowseDialog. Hence, the question here is how to scroll to the selected folder in the FolderBrowserDialog. The following StackOverflow thread is quite useful on this topic: http://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dialog-does-not-scroll-to-selected-folder

    By using the suggested solution, I have implemented it in RadBrowseEditor. Here is a sample code snippet which result is illustrated in the attached gif file:
    public RadForm1()
    {
        InitializeComponent();
     
        this.radBrowseEditor1.Value = @"C:\Program Files (x86)\Telerik";
        this.radBrowseEditor1.DialogType = Telerik.WinControls.UI.BrowseEditorDialogType.FolderBrowseDialog;
        FolderBrowserDialog dialog = this.radBrowseEditor1.Dialog as FolderBrowserDialog;
    }
     
    public class CustomBrowseEditor : RadBrowseEditor
    {
        public override string ThemeClassName 
        {
            get
            {
                return typeof(RadBrowseEditor).FullName; 
            }
        }
         
        protected override RadBrowseEditorElement CreateEditorElement()
        {
            return new CustomRadBrowseEditorElement();
        }
    }
     
    public class CustomRadBrowseEditorElement : RadBrowseEditorElement
    {
        protected override Type ThemeEffectiveType    
        {
            get   
            {
                return typeof(RadBrowseEditorElement);    
            }
        }
     
        protected override void OnBrowseButtonClick(EventArgs e)
        {
            InitializeDialog();
        
            // DialogResult result = this.Dialog.ShowDialog();
            DialogResult result = FolderBrowserLauncher.ShowFolderBrowser(this.Dialog as FolderBrowserDialog);
            if (result == DialogResult.OK)
            {
                bool wasReadOnly = this.ReadOnly;
     
                this.ReadOnly = false;
     
                SaveValueFromDialog();
     
                this.ReadOnly = wasReadOnly;
            }
     
            this.OnDialogClosed(new DialogClosedEventArgs(result));
        }
    }
     
    public static class FolderBrowserLauncher
    {
        /// <summary>
        /// Using title text to look for the top level dialog window is fragile.
        /// In particular, this will fail in non-English applications.
        /// </summary>
        const string _topLevelSearchString = "Browse For Folder";
     
        /// <summary>
        /// These should be more robust.  We find the correct child controls in the dialog
        /// by using the GetDlgItem method, rather than the FindWindow(Ex) method,
        /// because the dialog item IDs should be constant.
        /// </summary>
        const int _dlgItemBrowseControl = 0;
        const int _dlgItemTreeView = 100;
     
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     
        [DllImport("user32.dll")]
        static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
     
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
     
        /// <summary>
        /// Some of the messages that the Tree View control will respond to
        /// </summary>
        private const int TV_FIRST = 0x1100;
        private const int TVM_SELECTITEM = (TV_FIRST + 11);
        private const int TVM_GETNEXTITEM = (TV_FIRST + 10);
        private const int TVM_GETITEM = (TV_FIRST + 12);
        private const int TVM_ENSUREVISIBLE = (TV_FIRST + 20);
     
        /// <summary>
        /// Constants used to identity specific items in the Tree View control
        /// </summary>
        private const int TVGN_ROOT = 0x0;
        private const int TVGN_NEXT = 0x1;
        private const int TVGN_CHILD = 0x4;
        private const int TVGN_FIRSTVISIBLE = 0x5;
        private const int TVGN_NEXTVISIBLE = 0x6;
        private const int TVGN_CARET = 0x9;
     
        /// <summary>
        /// Calling this method is identical to calling the ShowDialog method of the provided
        /// FolderBrowserDialog, except that an attempt will be made to scroll the Tree View
        /// to make the currently selected folder visible in the dialog window.
        /// </summary>
        /// <param name="dlg"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static DialogResult ShowFolderBrowser(FolderBrowserDialog dlg, IWin32Window parent = null)
        {
            DialogResult result = DialogResult.Cancel;
            int retries = 10;
     
            using (Timer t = new Timer())
            {
                t.Tick += (s, a) =>
                {
                    if (retries > 0)
                    {
                        --retries;
                        IntPtr hwndDlg = FindWindow((string)null, _topLevelSearchString);
                        if (hwndDlg != IntPtr.Zero)
                        {
                            IntPtr hwndFolderCtrl = GetDlgItem(hwndDlg, _dlgItemBrowseControl);
                            if (hwndFolderCtrl != IntPtr.Zero)
                            {
                                IntPtr hwndTV = GetDlgItem(hwndFolderCtrl, _dlgItemTreeView);
     
                                if (hwndTV != IntPtr.Zero)
                                {
                                    IntPtr item = SendMessage(hwndTV, (uint)TVM_GETNEXTITEM, new IntPtr(TVGN_CARET), IntPtr.Zero);
                                    if (item != IntPtr.Zero)
                                    {
                                        SendMessage(hwndTV, TVM_ENSUREVISIBLE, IntPtr.Zero, item);
                                        retries = 0;
                                        t.Stop();
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        //
                        //  We failed to find the Tree View control.
                        //
                        //  As a fall back (and this is an UberUgly hack), we will send
                        //  some fake keystrokes to the application in an attempt to force
                        //  the Tree View to scroll to the selected item.
                        //
                        t.Stop();
                        SendKeys.Send("{TAB}{TAB}{DOWN}{DOWN}{UP}{UP}");
                    }
                };
     
                t.Interval = 10;
                t.Start();
     
                result = dlg.ShowDialog(parent);
            }
     
            return result;
        }
    }

    Make sure that in the designer file you use the custom RadBrowseEditor: 
    private void InitializeComponent()
    {
        this.radBrowseEditor1 = new CustomBrowseEditor();
    //...
    }

    I hope this information helps. Should you have further questions I would be glad to help.

    Regards,
    Dess
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Santosh
    Santosh avatar
    2 posts
    Member since:
    Jan 2017

    Posted 22 Jan 2017 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Great! It works like a charm now. Thank you.
Back to Top