TreeViewItem.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / TreeViewItem.cs / 3 / TreeViewItem.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Collections; 
using System.Collections.Specialized;
using System.ComponentModel; 
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls.Primitives; 
using System.Windows.Input;
using System.Windows.Media; 
using MS.Internal; 
using MS.Internal.KnownBoxes;
 
namespace System.Windows.Controls
{
    /// 
    ///     A child of a . 
    /// 
    [TemplatePart(Name = "PART_Header", Type = typeof(FrameworkElement))] 
    [StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(TreeViewItem))] 
    public class TreeViewItem : HeaderedItemsControl
    { 
        #region Constructors

        static TreeViewItem()
        { 
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(typeof(TreeViewItem)));
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(TreeViewItem)); 
 
            KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(KeyboardNavigationMode.Continue));
            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(KeyboardNavigationMode.None)); 
            IsTabStopProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));

            EventManager.RegisterClassHandler(typeof(TreeViewItem), FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler(OnRequestBringIntoView));
            EventManager.RegisterClassHandler(typeof(TreeViewItem), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseButtonDown), true); 
        }
 
        ///  
        ///     Creates an instance of this control.
        ///  
        public TreeViewItem()
        {
        }
 
        #endregion
 
        #region Public Properties 

        ///  
        ///     The DependencyProperty for the  property.
        ///     Default Value: false
        /// 
        public static readonly DependencyProperty IsExpandedProperty = 
            DependencyProperty.Register(
                    "IsExpanded", 
                    typeof(bool), 
                    typeof(TreeViewItem),
                    new FrameworkPropertyMetadata( 
                            BooleanBoxes.FalseBox,
                            new PropertyChangedCallback(OnIsExpandedChanged)));

        ///  
        ///     Specifies whether this item has expanded its children or not.
        ///  
        public bool IsExpanded 
        {
            get { return (bool) GetValue(IsExpandedProperty); } 
            set { SetValue(IsExpandedProperty, value); }
        }

        private bool CanExpand 
        {
            get { return HasItems; } 
        } 

        private static void OnIsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            TreeViewItem item = (TreeViewItem) d;
            bool isExpanded = (bool) e.NewValue;
 
            if (!isExpanded)
            { 
                TreeView tv = item.ParentTreeView; 
                if (tv != null)
                { 
                    tv.HandleSelectionAndCollapsed(item);
                }
            }
 
            TreeViewItemAutomationPeer peer = UIElementAutomationPeer.FromElement(item) as TreeViewItemAutomationPeer;
            if (peer != null) 
            { 
                peer.RaiseExpandCollapseAutomationEvent((bool)e.OldValue, isExpanded);
            } 

            if (isExpanded)
            {
                item.OnExpanded(new RoutedEventArgs(ExpandedEvent, item)); 
            }
            else 
            { 
                item.OnCollapsed(new RoutedEventArgs(CollapsedEvent, item));
            } 
        }

        /// 
        ///     The DependencyProperty for the  property. 
        ///     Default Value: false
        ///  
        public static readonly DependencyProperty IsSelectedProperty = 
            DependencyProperty.Register(
                    "IsSelected", 
                    typeof(bool),
                    typeof(TreeViewItem),
                    new FrameworkPropertyMetadata(
                            BooleanBoxes.FalseBox, 
                            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                            new PropertyChangedCallback(OnIsSelectedChanged))); 
 
        /// 
        ///     Specifies whether this item is selected or not. 
        /// 
        public bool IsSelected
        {
            get { return (bool) GetValue(IsSelectedProperty); } 
            set { SetValue(IsSelectedProperty, value); }
        } 
 
        private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            TreeViewItem item = (TreeViewItem)d;
            bool isSelected = (bool) e.NewValue;

            item.Select(isSelected); 

            TreeViewItemAutomationPeer peer = UIElementAutomationPeer.FromElement(item) as TreeViewItemAutomationPeer; 
            if (peer != null) 
            {
                peer.RaiseAutomationIsSelectedChanged(isSelected); 
            }

            if (isSelected)
            { 
                item.OnSelected(new RoutedEventArgs(SelectedEvent, item));
            } 
            else 
            {
                item.OnUnselected(new RoutedEventArgs(UnselectedEvent, item)); 
            }
        }

        ///  
        ///     DependencyProperty for .
        ///  
        public static readonly DependencyProperty IsSelectionActiveProperty = Selector.IsSelectionActiveProperty.AddOwner(typeof(TreeViewItem)); 

        ///  
        ///     Indicates whether the keyboard focus is within the TreeView.
        ///     When keyboard focus moves to a Menu or Toolbar, then the selection remains active.
        ///     Use this property to style the TreeViewItem to look different when focus is not within the TreeView.
        ///  
        [Browsable(false), Category("Appearance"), ReadOnly(true)]
        public bool IsSelectionActive 
        { 
            get
            { 
                return (bool)GetValue(IsSelectionActiveProperty);
            }
        }
 
        #endregion
 
        #region Public Events 

        ///  
        ///     Event fired when  becomes true.
        /// 
        public static readonly RoutedEvent ExpandedEvent = EventManager.RegisterRoutedEvent("Expanded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem));
 
        /// 
        ///     Event fired when  becomes true. 
        ///  
        [Category("Behavior")]
        public event RoutedEventHandler Expanded 
        {
            add
            {
                AddHandler(ExpandedEvent, value); 
            }
 
            remove 
            {
                RemoveHandler(ExpandedEvent, value); 
            }
        }

        ///  
        ///     Called when  becomes true.
        ///     Default implementation fires the  event. 
        ///  
        /// Event arguments.
        protected virtual void OnExpanded(RoutedEventArgs e) 
        {
            RaiseEvent(e);
        }
 
        /// 
        ///     Event fired when  becomes false. 
        ///  
        public static readonly RoutedEvent CollapsedEvent = EventManager.RegisterRoutedEvent("Collapsed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem));
 
        /// 
        ///     Event fired when  becomes false.
        /// 
        [Category("Behavior")] 
        public event RoutedEventHandler Collapsed
        { 
            add 
            {
                AddHandler(CollapsedEvent, value); 
            }

            remove
            { 
                RemoveHandler(CollapsedEvent, value);
            } 
        } 

        ///  
        ///     Called when  becomes false.
        ///     Default implementation fires the  event.
        /// 
        /// Event arguments. 
        protected virtual void OnCollapsed(RoutedEventArgs e)
        { 
            RaiseEvent(e); 
        }
 
        /// 
        ///     Event fired when  becomes true.
        /// 
        public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); 

        ///  
        ///     Event fired when  becomes true. 
        /// 
        [Category("Behavior")] 
        public event RoutedEventHandler Selected
        {
            add
            { 
                AddHandler(SelectedEvent, value);
            } 
 
            remove
            { 
                RemoveHandler(SelectedEvent, value);
            }
        }
 
        /// 
        ///     Called when  becomes true. 
        ///     Default implementation fires the  event. 
        /// 
        /// Event arguments. 
        protected virtual void OnSelected(RoutedEventArgs e)
        {
            RaiseEvent(e);
        } 

        ///  
        ///     Event fired when  becomes false. 
        /// 
        public static readonly RoutedEvent UnselectedEvent = EventManager.RegisterRoutedEvent("Unselected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); 

        /// 
        ///     Event fired when  becomes false.
        ///  
        [Category("Behavior")]
        public event RoutedEventHandler Unselected 
        { 
            add
            { 
                AddHandler(UnselectedEvent, value);
            }

            remove 
            {
                RemoveHandler(UnselectedEvent, value); 
            } 
        }
 
        /// 
        ///     Called when  becomes false.
        ///     Default implementation fires the  event.
        ///  
        /// Event arguments.
        protected virtual void OnUnselected(RoutedEventArgs e) 
        { 
            RaiseEvent(e);
        } 

        #endregion

        #region Implementation 

        #region Tree 
 
        /// 
        ///     Walks up the parent chain of TreeViewItems to the top TreeView. 
        /// 
        internal TreeView ParentTreeView
        {
            get 
            {
                ItemsControl parent = ParentItemsControl; 
                while (parent != null) 
                {
                    TreeView tv = parent as TreeView; 
                    if (tv != null)
                    {
                        return tv;
                    } 

                    parent = ItemsControl.ItemsControlFromItemContainer(parent); 
                } 

                return null; 
            }
        }

        ///  
        ///     Returns the immediate parent TreeViewItem. Null if the parent is a TreeView.
        ///  
        internal TreeViewItem ParentTreeViewItem 
        {
            get 
            {
                return ParentItemsControl as TreeViewItem;
            }
        } 

        ///  
        ///     Returns the immediate parent ItemsControl. 
        /// 
        internal ItemsControl ParentItemsControl 
        {
            get
            {
                return ItemsControl.ItemsControlFromItemContainer(this); 
            }
        } 
 
        #endregion
 
        #region Selection

        /// 
        /// Called when the visual parent of this element changes. 
        /// 
        ///  
        protected internal override void OnVisualParentChanged(DependencyObject oldParent) 
        {
            // When TreeViewItem is added to the visual tree we check if IsSelected is set to true 
            // In this case we need to update the tree selection
            if (VisualTreeHelper.GetParent(this) != null)
            {
                if (IsSelected) 
                {
                    Select(true); 
                } 
            }
 
            base.OnVisualParentChanged(oldParent);
        }

        private void Select(bool selected) 
        {
            TreeView tree = ParentTreeView; 
            ItemsControl parent = ParentItemsControl; 
            if ((tree != null) && (parent != null) && !tree.IsSelectionChangeActive)
            { 
                // Give the TreeView a reference to this container and its data
                object data = parent.GetItemOrContainerFromContainer(this);
                tree.ChangeSelection(data, this, selected);
            } 
        }
 
        private bool ContainsSelection 
        {
            get { return _bits[(int)Bits.ContainsSelection]; } 
            set { _bits[(int)Bits.ContainsSelection] = value; }
        }

        internal void UpdateContainsSelection(bool selected) 
        {
            TreeViewItem parent = ParentTreeViewItem; 
            while (parent != null) 
            {
                parent.ContainsSelection = selected; 
                parent = parent.ParentTreeViewItem;
            }
        }
 
        #endregion
 
        #region Input 

        ///  
        ///     This method is invoked when the IsFocused property changes to true.
        /// 
        /// Event arguments.
        protected override void OnGotFocus(RoutedEventArgs e) 
        {
            Select(true); 
            base.OnGotFocus(e); 
        }
 
        /// 
        ///     Called when the left mouse button is pressed down.
        /// 
        /// Event arguments 
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        { 
            if (!e.Handled && IsEnabled) 
            {
                if (Focus()) 
                {
                    e.Handled = true;
                }
 
                if ((e.ClickCount % 2) == 0)
                { 
                    IsExpanded = !IsExpanded; 
                    e.Handled = true;
                } 
            }
            base.OnMouseLeftButtonDown(e);
        }
 
        /// 
        ///     Called when a keyboard key is pressed down. 
        ///  
        /// Event Arguments
        protected override void OnKeyDown(KeyEventArgs e) 
        {
            base.OnKeyDown(e);
            if (!e.Handled)
            { 
                switch (e.Key)
                { 
                    case Key.Add: 
                        if (CanExpandOnInput && !IsExpanded)
                        { 
                            IsExpanded = true;
                            e.Handled = true;
                        }
                        break; 

                    case Key.Subtract: 
                        if (CanExpandOnInput && IsExpanded) 
                        {
                            IsExpanded = false; 
                            e.Handled = true;
                        }
                        break;
 
                    case Key.Left:
                    case Key.Right: 
                        if (LogicalLeft(e.Key)) 
                        {
                            if (!IsControlKeyDown && CanExpandOnInput && IsExpanded) 
                            {
                                if (IsFocused)
                                {
                                    IsExpanded = false; 
                                }
                                else 
                                { 
                                    Focus();
                                } 
                                e.Handled = true;
                            }
                        }
                        else 
                        {
                            if (!IsControlKeyDown && CanExpandOnInput) 
                            { 
                                if (!IsExpanded)
                                { 
                                    IsExpanded = true;
                                    e.Handled = true;
                                }
                                else if (HandleDownKey()) 
                                {
                                    e.Handled = true; 
                                } 
                            }
                        } 
                        break;

                    case Key.Down:
                        if (!IsControlKeyDown && HandleDownKey()) 
                        {
                            e.Handled = true; 
                        } 
                        break;
 
                    case Key.Up:
                        if (!IsControlKeyDown && HandleUpKey())
                        {
                            e.Handled = true; 
                        }
                        break; 
                } 
            }
        } 

        private bool LogicalLeft(Key key)
        {
            bool invert = (FlowDirection == FlowDirection.RightToLeft); 
            return (!invert && (key == Key.Left)) || (invert && (key == Key.Right));
        } 
 
        private static bool IsControlKeyDown
        { 
            get
            {
                return ((Keyboard.Modifiers & ModifierKeys.Control) == (ModifierKeys.Control));
            } 
        }
 
        private bool CanExpandOnInput 
        {
            get 
            {
                return CanExpand && IsEnabled;
            }
        } 

        internal bool HandleUpKey() 
        { 
            if (AllowHandleKeyEvent(FocusNavigationDirection.Up))
            { 
                ItemsControl parent = ParentItemsControl;
                if (parent != null)
                {
                    int index = parent.ItemContainerGenerator.IndexFromContainer(this); 
                    while (index > 0)
                    { 
                        index--; 
                        TreeViewItem item = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                        if ((item != null) && item.IsEnabled) 
                        {
                            return FocusIntoItem(item);
                        }
                    } 

                    if (index == 0) 
                    { 
                        if (parent != ParentTreeView)
                        { 
                            return parent.Focus();
                        }
                        else
                        { 
                            return true; // Prevents KeyboardNavigation from focusing one of our children
                        } 
                    } 
                }
            } 

            return false; // Not handled
        }
 
        internal bool HandleDownKey()
        { 
            if (AllowHandleKeyEvent(FocusNavigationDirection.Down)) 
            {
                if (IsExpanded && CanExpand) 
                {
                    TreeViewItem item = ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem;
                    if (item != null)
                    { 
                        if (item.IsEnabled)
                        { 
                            return item.Focus(); 
                        }
                        else 
                        {
                            item.FocusDown();
                        }
                    } 
                }
                else 
                { 
                    return FocusDown();
                } 
            }

            return false; // Not handled
        } 

        private bool AllowHandleKeyEvent(FocusNavigationDirection direction) 
        { 
            if (!IsSelected)
            { 
                return false;
            }

            DependencyObject currentFocus = Keyboard.FocusedElement as DependencyObject; 
            if (currentFocus != null && UIElementHelper.IsUIElementOrUIElement3D(currentFocus))
            { 
                DependencyObject predict = UIElementHelper.PredictFocus(currentFocus, direction); 
                if (predict != currentFocus)
                { 
                    while (predict != null)
                    {
                        TreeViewItem item = predict as TreeViewItem;
                        if (item == this) 
                        {
                            return false; // There is a focusable item in the header 
                        } 
                        else if ((item != null) || (predict is TreeView))
                        { 
                            return true;
                        }

                        predict = VisualTreeHelper.GetParent(predict); 
                    }
                } 
            } 

            return true; 
        }

        internal static bool FocusIntoItem(TreeViewItem item)
        { 
            Debug.Assert(item.IsEnabled, "Only call FocusIntoItem with an enabled item");
 
            TreeViewItem lastItem = null; 

            // Find the last child in the subtree and focus it 
            int index = -1;
            TreeViewItem parent = null;
            while (item != null)
            { 
                if (item.IsEnabled)
                { 
                    if (!item.IsExpanded || !item.CanExpand) 
                    {
                        return item.Focus(); 
                    }

                    lastItem = item;
                    parent = item; 
                    index = item.Items.Count - 1;
                } 
                else if (index > 0) 
                {
                    index--; 
                }
                else
                {
                    break; 
                }
 
                item = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem; 
            }
 
            if (lastItem != null)
            {
                return lastItem.Focus();
            } 

            return false; 
        } 

        internal bool FocusDown() 
        {
            ItemsControl parent = ParentItemsControl;
            if (parent != null)
            { 
                TreeViewItem item;
                int index = parent.ItemContainerGenerator.IndexFromContainer(this); 
                int count = parent.Items.Count; 
                while (index < count)
                { 
                    // Focus the next sibling
                    index++;
                    item = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem;
                    if ((item != null) && item.IsEnabled && item.Focus()) 
                    {
                        return true; 
                    } 
                }
 
                // This item has no next sibling, focus the parent's next sibling
                item = parent as TreeViewItem;
                if (item != null)
                { 
                    return item.FocusDown();
                } 
            } 

            return false; // Not handled 
        }

        private static void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
        { 
            TreeViewItem tvi = (TreeViewItem)sender;
            TreeView tv = tvi.ParentTreeView; 
            if (tv != null) 
            {
                tv.HandleMouseButtonDown(); 
            }
        }
        private static void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
        { 
            if (e.TargetObject == sender)
            { 
                ((TreeViewItem)sender).HandleBringIntoView(e); 
            }
        } 

        private void HandleBringIntoView(RequestBringIntoViewEventArgs e)
        {
            TreeViewItem parent = ParentTreeViewItem; 
            while (parent != null)
            { 
                if (!parent.IsExpanded) 
                {
                    parent.IsExpanded = true; 
                }

                parent = parent.ParentTreeViewItem;
            } 

            // See FrameworkElement.BringIntoView() comments 
            //[....], bug 1126518. On new/updated elements RenderSize isn't yet computed 
            //so we need to postpone the rect computation until layout is done.
            //this is accomplished by passing Empty rect here and then asking for RenderSize 
            //in IScrollInfo when it actually executes an async MakeVisible command.
            if (e.TargetRect.IsEmpty)
            {
                FrameworkElement header = HeaderElement; 
                if (header != null)
                { 
                    e.Handled = true; 
                    header.BringIntoView();
                } 
            }
        }

        private FrameworkElement HeaderElement 
        {
            get 
            { 
                return GetTemplateChild(HeaderPartName) as FrameworkElement;
            } 
        }

        internal bool HandleScrollByPage(bool up, ScrollViewer scroller, double viewportHeight, double startTop, double startBottom, out double currentDelta)
        { 
            double closeEdge;
            currentDelta = CalculateDelta(up, this, scroller, startTop, startBottom, out closeEdge); 
            if (DoubleUtil.GreaterThan(closeEdge, viewportHeight)) 
            {
                // The item does not fit in view at all 
                return false; // Did not focus
            }
            else if (DoubleUtil.LessThanOrClose(currentDelta, viewportHeight))
            { 
                // This item and all its children fit in view.
                // There may be others that also fit in view, so don't focus now 
                return false; // Did not focus 
            }
            else 
            {
                // This item is partially in view

                // Test if the header element is in view 
                bool headerInView = false;
                FrameworkElement header = HeaderElement; 
                if (header != null) 
                {
                    double delta = CalculateDelta(up, header, scroller, startTop, startBottom); 
                    if (DoubleUtil.LessThanOrClose(delta, viewportHeight))
                    {
                        // The header is in view
                        headerInView = true; 
                    }
                } 
 
                TreeViewItem select = null;
                int count = Items.Count; 
                bool skip = up && ContainsSelection;
                for (int index = (up ? count - 1 : 0); (0 <= index) && (index < count); index = index + (up ? -1 : 1))
                {
                    TreeViewItem item = ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem; 
                    if ((item != null) && item.IsEnabled)
                    { 
                        if (skip) 
                        {
                            if (item.IsSelected) 
                            {
                                skip = false;
                                continue; // Go to the next one
                            } 
                            else if (item.ContainsSelection)
                            { 
                                skip = false; 
                                // Look inside this one
                            } 
                            else
                            {
                                continue;
                            } 
                        }
 
                        double delta; 
                        if (item.HandleScrollByPage(up, scroller, viewportHeight, startTop, startBottom, out delta))
                        { 
                            // This item or one of its children was focused
                            return true;
                        }
                        else if (DoubleUtil.GreaterThan(delta, viewportHeight)) 
                        {
                            // This item does not fit 
                            break; 
                        }
                        else 
                        {
                            // This item does fit, but we should continue searching
                            select = item;
                        } 
                    }
                } 
 
                if (select != null)
                { 
                    // Earlier we found an item that fit but didn't focus it at that time
                    if (up)
                    {
                        return select.Focus(); 
                    }
                    else 
                    { 
                        return FocusIntoItem(select);
                    } 
                }
                else if (headerInView)
                {
                    // None of the children could be focused, the header is in view even though 
                    // the whole subtree isn't in view. There shouldn't be any more focusable
                    // items that fit, so select this one. 
                    return Focus(); 
                }
            } 

            return false; // Did not focus
        }
 
        private static double CalculateDelta(bool up, FrameworkElement item, ScrollViewer scroller, double startTop, double startBottom)
        { 
            double closeEdge; 
            return CalculateDelta(up, item, scroller, startTop, startBottom, out closeEdge);
        } 

        private static double CalculateDelta(bool up, FrameworkElement item, ScrollViewer scroller, double startTop, double startBottom, out double closeEdge)
        {
            double top, bottom; 
            GetTopAndBottom(item, scroller, out top, out bottom);
 
            if (up) 
            {
                closeEdge = startBottom - bottom; 
                return startBottom - top;
            }
            else
            { 
                closeEdge = top - startTop;
                return bottom - startTop; 
            } 
        }
 
        internal void GetTopAndBottom(Visual parent, out double top, out double bottom)
        {
            FrameworkElement header = HeaderElement;
            if (header != null) 
            {
                GetTopAndBottom(header, parent, out top, out bottom); 
            } 
            else
            { 
                GetTopAndBottom(this, parent, out top, out bottom);
            }
        }
 
        private static void GetTopAndBottom(FrameworkElement item, Visual parent, out double top, out double bottom)
        { 
            GeneralTransform transform = item.TransformToAncestor(parent); 

            Point upperLeft; 
            if (transform.TryTransform(new Point(0.0, 0.0), out upperLeft))
            {
                top = upperLeft.Y;
            } 
            else
            { 
                top = 0.0; 
            }
 
            Point lowerLeft;
            if (transform.TryTransform(new Point(0.0, item.RenderSize.Height), out lowerLeft))
            {
                bottom = lowerLeft.Y; 
            }
            else 
            { 
                bottom = top + item.RenderSize.Height;
            } 
        }

        #endregion
 
        #region Containers
 
        ///  
        ///     Returns true if the item is or should be its own container.
        ///  
        /// The item to test.
        /// true if its type matches the container type.
        protected override bool IsItemItsOwnContainerOverride(object item)
        { 
            return item is TreeViewItem;
        } 
 
        /// 
        ///     Create or identify the element used to display the given item. 
        /// 
        /// The container.
        protected override DependencyObject GetContainerForItemOverride()
        { 
            return new TreeViewItem();
        } 
 
        /// 
        ///     This method is invoked when the Items property changes. 
        /// 
        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action) 
            {
                case NotifyCollectionChangedAction.Remove: 
                case NotifyCollectionChangedAction.Reset: 
                    if (ContainsSelection)
                    { 
                        TreeView tree = ParentTreeView;
                        if ((tree != null) && !tree.IsSelectedContainerHookedUp)
                        {
                            ContainsSelection = false; 
                            Select(true);
                        } 
                    } 
                    break;
 
                case NotifyCollectionChangedAction.Replace:
                    if (ContainsSelection)
                    {
                        TreeView tree = ParentTreeView; 
                        if (tree != null)
                        { 
                            // When Selected item is replaced - remove the selection 
                            // Revisit the condition when we support duplicate items in Items collection: if e.OldItems[0] is the same as selected items we will unselect the selected item
                            object selectedItem = tree.SelectedItem; 
                            if ((selectedItem != null) && selectedItem.Equals(e.OldItems[0]))
                            {
                                tree.ChangeSelection(selectedItem, tree.SelectedContainer, false);
                            } 
                        }
                    } 
                    break; 

                case NotifyCollectionChangedAction.Add: 
                case NotifyCollectionChangedAction.Move:
                    break;

                default: 
                    throw new NotSupportedException(SR.Get(SRID.UnexpectedCollectionChangeAction, e.Action));
            } 
        } 

        #endregion 

        #region Automation
        /// 
        /// Creates AutomationPeer () 
        /// 
        protected override AutomationPeer OnCreateAutomationPeer() 
        { 
            return new TreeViewItemAutomationPeer(this);
        } 
        #endregion Automation

        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types. 
        internal override DependencyObjectType DTypeThemeStyleKey 
        {
            get { return _dType; } 
        }

        private static DependencyObjectType _dType;
 
        #endregion DTypeThemeStyleKey
 
        #endregion 

        #region Data 

        private enum Bits
        {
            ContainsSelection       = 0x10, 
        }
 
        // Packed boolean information 
        private BitVector32 _bits = new BitVector32(0);
 
        private const string HeaderPartName = "PART_Header";

        #endregion
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK