Click here to Skip to main content
15,881,715 members
Articles / Programming Languages / C#

Silverlight Auto Complete Treeview

Rate me:
Please Sign up or sign in to vote.
4.70/5 (7 votes)
18 Jun 2009CPOL5 min read 42.7K   1.6K   18  
Silverlight auto-complete treeview which takes hierarchical data as its datasource.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Collections.ObjectModel;


namespace AutoCompleteTextBox
{
    public partial class MainPage : UserControl
    {

        #region Variable Declarations
            TreeViewItem tv;
            HierarchicalCity selectedTV;
            HierarchicalCity SelectedClass;
            bool selectedText;
            bool IsTextboxFocus = false;
            long LastTicks;
        #endregion
        public MainPage()
        {
            InitializeComponent();
            XDocument loaded = XDocument.Load("City.xml");
            inputBox.ItemsSource = from x in loaded.Descendants("Row")
                                   select (string)x.Attribute("CityName");
            tvData.ItemsSource = Model.GetData();
        }

#region TreeView Events

        private void tvData_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (tvData.SelectedItem != null)
            {
                if (tvData.SelectedItem.GetType().ToString() == "AutoCompleteTextBox.HierarchicalCity")
                {
                    tv = tvData.ContainerFromItem(tvData.SelectedItem);
                    if (IsTextboxFocus == false)
                    {
                        txtCity.Text = ((HierarchicalCity)tvData.SelectedItem).CityName;
                        selectedText = true;
                    }
                    SelectedClass = (HierarchicalCity)tvData.SelectedItem;
                }
                else if (tvData.SelectedItem.GetType().ToString() == "AutoCompleteTextBox.SilverlightTreeViewItem")
                {
                    tv = (TreeViewItem)tvData.SelectedItem;
                }
            }
        }

        private void tvData_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape || e.Key == Key.Enter)
            {
                if (e.Key == Key.Enter && SelectedClass != null)
                {
                    txtCity.Text = SelectedClass.CityName;
                    selectedText = true;
                }
                txtCity.Focus();
                HideTreeview();
            }
        }

        private void tvData_GotFocus(object sender, RoutedEventArgs e)
        {
            GoToItem();
        }

        private void tvData_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if ((DateTime.Now.Ticks - LastTicks) < 2310000)
            {
                if (SelectedClass != null)
                {
                    selectedText = true;
                    txtCity.Text = SelectedClass.CityName;
                }
                txtCity.Focus();
                HideTreeview();
                //PopupControl.IsOpen = false;
            }
            LastTicks = DateTime.Now.Ticks;
            //if (tv != null)
            //    tv.Focus();
        }

        private void tvData_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckFocus();
        }

        #endregion

#region Other Functions

        void CheckFocus()
        {
            
            DependencyObject dp = ((DependencyObject)System.Windows.Input.FocusManager.GetFocusedElement());
            if (dp != null)
            {
                if (((Control)dp).Name == "txtCity" || dp.GetType().Name == "SilverlightTreeViewItem" || dp.GetType().Name == "SilverlightTreeView")
                {
                }
                else
                {
                    HideTreeview();
                }
            }
            else
            {
                HideTreeview();
            }
        }

        private void HideTreeview()
        {
            PopupControl.IsOpen = false;
            tv = null;
            SelectedClass = null;
            foreach (HierarchicalCity item in tvData.Items)
            {
                item.CollapseAll();
            }
        }

        private void ReturnConditions(string val)
        {
            selectedTV = null;
            for (int i = 0; i < Model.GetCurrentData().Count; i++)
            {


                if (Model.GetCurrentData()[i].CityName.StartsWith(val, StringComparison.OrdinalIgnoreCase))
                {
                    selectedTV = Model.GetCurrentData()[i];
                    ExpandAllParents(Model.GetCurrentData()[i]);
                }
                else if (Model.GetCurrentData()[i].SubClass != null)
                {
                    ReturnChildconditionsRecursively(Model.GetCurrentData()[i].SubClass, val);
                }
            }
            if (selectedTV == null)
            {
                HideTreeview();
            }
        }
        private void ReturnChildconditionsRecursively(ObservableCollection<HierarchicalCity> lst,string val)
        {
            for (int j = 0; j < lst.Count; j++)
            {
                if (lst[j].CityName.StartsWith(val,StringComparison.OrdinalIgnoreCase))
                {
                    selectedTV = lst[j];
                    ExpandAllParents(lst[j]);
                    break;
                }
                else if (lst[j].SubClass != null)
                {
                    ReturnChildconditionsRecursively(lst[j].SubClass,val);
                }
            }

        }

        private void ExpandAllParents(HierarchicalCity t)
        {
            SelectedClass = t;
            foreach (HierarchicalCity item in tvData.Items)
            {
                if (item.ExpandSuperclasses(t))
                {
                    t.IsSelected = true;
                    break;
                }
            }

        }

        void GoToItem()
        {
            PopupControl.HorizontalOffset = 31;
            PopupControl.VerticalOffset = 49;
            PopupControl.IsOpen = true;
            ReturnConditions(txtCity.Text);
        }
#endregion

#region Textbox Events

        private void txtCity_GotFocus(object sender, RoutedEventArgs e)
        {
            IsTextboxFocus = true;
        }

        private void txtCity_LostFocus(object sender, RoutedEventArgs e)
        {
            CheckFocus();
            IsTextboxFocus = false;
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (txtCity.Text == "")
            {
                HideTreeview();
            }
            else if (selectedText == false) 
            {
                GoToItem();
            }
        }

        private void txtCity_KeyUp(object sender, KeyEventArgs e)
        {
            
            if (e.Key == Key.Enter && SelectedClass != null)
            {
                txtCity.Text = SelectedClass.CityName;
                selectedText = true;
                HideTreeview();
            }
            else if ((e.Key == Key.Down || e.Key == Key.Up) && tv != null)
            {
                tv.Focus();
            }
            else if (e.Key == Key.Escape)
            {
                HideTreeview();
            }
        }

        private void txtCity_KeyDown(object sender, KeyEventArgs e)
        {
            selectedText = false;
        }

        #endregion
    }    
}

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 Code Project Open License (CPOL)


Written By
Team Leader Phoenix Tech Labs
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions