Click here to Skip to main content
15,892,059 members
Articles / Desktop Programming / WPF

WPF Breadcrumb Folder TextBox

Rate me:
Please Sign up or sign in to vote.
4.41/5 (10 votes)
15 Jan 2009LGPL36 min read 101K   1.7K   71  
This article provides an implementation of a WPF Breadcrumb control, and describes how to develop one.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using QuickZip.UserControls.Breadcrumb.Presenter;
using QuickZip.UserControls.Breadcrumb.Framework;
using System.Windows.Controls.Primitives;
using System.Diagnostics;

namespace QuickZip.UserControls.Breadcrumb.View
{
    /// <summary>
    /// Interaction logic for TextBox.xaml
    /// </summary>
    public partial class AutoCompleteTextBoxView : TextBox 
    {
        public static DependencyProperty RootProperty = DependencyProperty.Register("Root", typeof(BreadcrumbItemBase), typeof(AutoCompleteTextBoxView),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(RootChanged)));

        internal Popup Popup { get { return this.Template.FindName("PART_Popup", this) as Popup; } }
        internal ListBox ItemList { get { return this.Template.FindName("PART_ItemList", this) as ListBox; } }
        //12-25-08 : Add Ghost image when picking from ItemList
        internal TextBlock TempVisual { get { return this.Template.FindName("PART_TempVisual", this) as TextBlock; } }
        internal ScrollViewer Host { get { return this.Template.FindName("PART_ContentHost", this) as ScrollViewer; } }
        internal UIElement TextBoxView { get { foreach (object o in LogicalTreeHelper.GetChildren(Host)) return o as UIElement; return null; } }
        private bool _loaded = false;
        private string _lastPath;

        public AutoCompleteTextBoxView()
        {
            InitializeComponent();
        }

        public static void RootChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            AutoCompleteTextBoxView atv = (AutoCompleteTextBoxView)obj;
            BreadcrumbItemBase newRoot = e.NewValue as BreadcrumbItemBase;

            atv.Presenter._root = newRoot;
        }
       

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _loaded = true;

            this.AddHandler(AutoCompleteTextBoxView.GotKeyboardFocusEvent, (RoutedEventHandler)delegate { this.SelectionStart = this.Text.Length; });
            
            this.KeyDown += new KeyEventHandler(AutoCompleteTextBox_KeyDown);
            this.PreviewKeyDown += new KeyEventHandler(AutoCompleteTextBox_PreviewKeyDown);
            ItemList.PreviewMouseDown += new MouseButtonEventHandler(ItemList_PreviewMouseDown);
            ItemList.KeyDown += new KeyEventHandler(ItemList_KeyDown);
            
            this.Focus();
        }

        public AutoCompleteTextBoxPresenter Presenter { get { return DataContext as AutoCompleteTextBoxPresenter; } }

        void updateSource()
        {
            if (this.GetBindingExpression(TextBox.TextProperty) != null)
                this.GetBindingExpression(TextBox.TextProperty).UpdateSource();            
        }

        void AutoCompleteTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {                
                updateSource();
                Popup.IsOpen = false;
            }
        }

        public void CheckPopupIsOpen()
        {
            if (Popup != null) //Component inited?.
            {
                Popup.IsOpen = ItemList.Items.Count > 0;
                TextBoxView.Focus();
            }
        }

        void AutoCompleteTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            //12-25-08 - added PageDown Support
            if (ItemList.Items.Count > 0 && !(e.OriginalSource is ListBoxItem))
                switch (e.Key)
                {
                    case Key.Up:
                    case Key.Down:
                    case Key.Prior:
                    case Key.Next:
                        ItemList.Focus();
                        ItemList.SelectedIndex = 0;
                        ListBoxItem lbi = ItemList.ItemContainerGenerator.ContainerFromIndex(ItemList.SelectedIndex) as ListBoxItem;
                        if (lbi != null)  lbi.Focus(); //01-05-08 Fix crash
                        _lastPath = Text;
                        e.Handled = true;
                        break;

                }
        }

        void ItemList_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.OriginalSource is ListBoxItem)
            {

                ListBoxItem tb = e.OriginalSource as ListBoxItem;

                e.Handled = true;
                switch (e.Key)
                {
                    case Key.Enter:
                        Text = (tb.Content as string); updateSource(); break;
                    //12-25-08 - added "\" support when picking in list view
                    case Key.Oem5: // "\" Button
                        Text = (tb.Content as string) + "\\";                        
                        break;
                    //12-25-08 - roll back if escape is pressed
                    case Key.Escape:
                        Text = _lastPath.TrimEnd('\\') + "\\";
                        break;
                    default: e.Handled = false; break;
                }
                //12-25-08 - Force focus back the control after selected.
                if (e.Handled)
                {
                    Keyboard.Focus(this);
                    if (e.Key != Key.Oem5) Popup.IsOpen = false; //01-07-09 Fixed Popup not Open if \ pressed.
                    this.Select(Text.Length, 0); //Select last char
                }
            }
        }

        void ItemList_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                TextBlock tb = e.OriginalSource as TextBlock;
                if (tb != null)
                {
                    Text = tb.Text;
                    updateSource();
                    Popup.IsOpen = false;
                    e.Handled = true;
                }
            }
        }


        //protected override void OnTextChanged(TextChangedEventArgs e)
        //{
        //    //Presenter.SelectedFolder = this.Text;
        //}

        protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
        {
            e.Handled = true;
        }


        private void root_Loaded(object sender, RoutedEventArgs e)
        {
                    
        }


    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Founder
Hong Kong Hong Kong

Comments and Discussions