Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / Controls / TreeViewItem.cs / 1 / 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, VirtualizingStackPanel.IProvideStackingSize { #region Constructors static TreeViewItem() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(typeof(TreeViewItem))); VirtualizingStackPanel.IsVirtualizingProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox)); _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 public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register( "IsExpanded", typeof(bool), typeof(TreeViewItem), new FrameworkPropertyMetadata( BooleanBoxes.FalseBox, new PropertyChangedCallback(OnIsExpandedChanged))); ///property. /// Default Value: false /// /// 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 public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register( "IsSelected", typeof(bool), typeof(TreeViewItem), new FrameworkPropertyMetadata( BooleanBoxes.FalseBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnIsSelectedChanged))); ///property. /// Default Value: false /// /// 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 public static readonly RoutedEvent ExpandedEvent = EventManager.RegisterRoutedEvent("Expanded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes true. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Expanded { add { AddHandler(ExpandedEvent, value); } remove { RemoveHandler(ExpandedEvent, value); } } ///becomes true. /// /// Called when /// Event arguments. protected virtual void OnExpanded(RoutedEventArgs e) { RaiseEvent(e); } ///becomes true. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent CollapsedEvent = EventManager.RegisterRoutedEvent("Collapsed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes false. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Collapsed { add { AddHandler(CollapsedEvent, value); } remove { RemoveHandler(CollapsedEvent, value); } } ///becomes false. /// /// Called when /// Event arguments. protected virtual void OnCollapsed(RoutedEventArgs e) { RaiseEvent(e); } ///becomes false. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes true. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Selected { add { AddHandler(SelectedEvent, value); } remove { RemoveHandler(SelectedEvent, value); } } ///becomes true. /// /// Called when /// Event arguments. protected virtual void OnSelected(RoutedEventArgs e) { RaiseEvent(e); } ///becomes true. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent UnselectedEvent = EventManager.RegisterRoutedEvent("Unselected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes false. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Unselected { add { AddHandler(UnselectedEvent, value); } remove { RemoveHandler(UnselectedEvent, value); } } ///becomes false. /// /// Called when /// Event arguments. protected virtual void OnUnselected(RoutedEventArgs e) { RaiseEvent(e); } #endregion #region Internal Methods ///becomes false. /// Default implementation fires the event. /// /// TreeView keeps track of the size estimate; forward the call to it. /// ///double VirtualizingStackPanel.IProvideStackingSize.EstimatedContainerSize(bool isHorizontal) { TreeView parent = ParentTreeView; Size estimate = Size.Empty; if (parent != null) { estimate = ParentTreeView.CurrentContainerSizeEstimate; } return isHorizontal ? estimate.Width : estimate.Height; } /// /// Return the size of the header in the requested direction. /// /// ///double VirtualizingStackPanel.IProvideStackingSize.HeaderSize(bool isHorizontal) { UIElement header = null; ControlTemplate template = Template; if (template != null) { header = template.FindName("PART_Header", this) as UIElement; if (header != null) { return isHorizontal ? header.DesiredSize.Width : header.DesiredSize.Height; } } return 0d; } #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 ReadControlFlag(ControlBoolFlags.ContainsSelection); } set { WriteControlFlag(ControlBoolFlags.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 item = FindPreviousFocusableItem(); if (item != null) { if (item == ParentItemsControl && item == ParentTreeView) { return true; // Prevents KeyboardNavigation from focusing one of our children } return item.Focus(); } } return false; // Not handled } internal bool HandleDownKey() { if (AllowHandleKeyEvent(FocusNavigationDirection.Down)) { 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 = FindLastFocusableItem(item); if (lastItem != null) { return lastItem.Focus(); } return false; } internal bool FocusDown() { TreeViewItem item = FindNextFocusableItem(true); if (item != null) { return item.Focus(); } return false; } ////// Returns the next item in the TreeView hierarchy, regardless of depth. /// ///private TreeViewItem FindNextFocusableItem(bool walkIntoSubtree) { // // First walk into this item's subtree // if (walkIntoSubtree && IsExpanded && CanExpand) { TreeViewItem item = ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem; if (item != null) { if (item.IsEnabled) { return item; } else { return item.FindNextFocusableItem(false); } } } // // Otherwise go to the next sibling // ItemsControl parent = ParentItemsControl; if (parent != null) { TreeViewItem item; int index = parent.ItemContainerGenerator.IndexFromContainer(this); int count = parent.Items.Count; while (index < count) { // Find the next sibling index++; item = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem; if ((item != null) && item.IsEnabled) { return item; } } // This item has no next sibling, find the parent's next sibling item = parent as TreeViewItem; if (item != null) { return item.FindNextFocusableItem(false); } } return null; // Not handled } /// /// Returns the previous item in the TreeView hierarchy, regardless of depth. /// ///private ItemsControl FindPreviousFocusableItem() { 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) { TreeViewItem lastItem = FindLastFocusableItem(item); if (lastItem != null) { return lastItem; } } } return parent; } return null; } /// /// Returns the last focusable item in the given subtree. /// ///private static TreeViewItem FindLastFocusableItem(TreeViewItem item) { Debug.Assert(item.IsEnabled, "Only call FocusIntoItem with an enabled item"); TreeViewItem lastItem = null; // Find the last child in the subtree. int index = -1; TreeViewItem parent = null; while (item != null) { if (item.IsEnabled) { if (!item.IsExpanded || !item.CanExpand) { return item; } 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; } return null; } /// /// This should be PredictFocus but since UIElement.PredictFocus is sealed by FE we can't override it. /// TreeViewItem has its own code for deciding where focus should go. /// /// ///internal DependencyObject InternalPredictFocus(FocusNavigationDirection direction) { switch (direction) { case FocusNavigationDirection.Left: case FocusNavigationDirection.Up: return FindPreviousFocusableItem(); case FocusNavigationDirection.Right: case FocusNavigationDirection.Down: return FindNextFocusableItem(true); default: return null; } } 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 //dmitryt, 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(); } ////// We only override this to help with container estimation for virtualization /// /// ///protected override Size MeasureOverride(Size constraint) { Size desiredSize = base.MeasureOverride(constraint); if (IsVirtualizing && !IsExpanded && IsVisible) { TreeView parent = ParentTreeView; if (parent != null) { parent.RegisterContainerSize(IsLogicalHorizontal ? desiredSize.Width : desiredSize.Height); } } return desiredSize; } /// /// Send down the IsVirtualizing property if it's set on this element. /// /// /// protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); IsVirtualizingPropagationHelper(this, element); } // Synchronizes the value of the child's IsVirtualizing property with that of the parent's internal static void IsVirtualizingPropagationHelper(DependencyObject parent, DependencyObject element) { SynchronizeValue(VirtualizingStackPanel.IsVirtualizingProperty, parent, element); SynchronizeValue(VirtualizingStackPanel.VirtualizationModeProperty, parent, element); } private static void SynchronizeValue(DependencyProperty dp, DependencyObject parent, DependencyObject child) { if (IsDefaultValue(dp, parent)) { child.ClearValue(dp); } else { object value = parent.GetValue(dp); child.SetValue(dp, value); } } private static bool IsDefaultValue(DependencyProperty dp, DependencyObject element) { bool hasModifiers; return element.GetValueSource(dp, null, out hasModifiers) == BaseValueSourceInternal.Default; } ////// 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 const string HeaderPartName = "PART_Header"; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // 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, VirtualizingStackPanel.IProvideStackingSize { #region Constructors static TreeViewItem() { DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(typeof(TreeViewItem))); VirtualizingStackPanel.IsVirtualizingProperty.OverrideMetadata(typeof(TreeViewItem), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox)); _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 public static readonly DependencyProperty IsExpandedProperty = DependencyProperty.Register( "IsExpanded", typeof(bool), typeof(TreeViewItem), new FrameworkPropertyMetadata( BooleanBoxes.FalseBox, new PropertyChangedCallback(OnIsExpandedChanged))); ///property. /// Default Value: false /// /// 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 public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register( "IsSelected", typeof(bool), typeof(TreeViewItem), new FrameworkPropertyMetadata( BooleanBoxes.FalseBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(OnIsSelectedChanged))); ///property. /// Default Value: false /// /// 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 public static readonly RoutedEvent ExpandedEvent = EventManager.RegisterRoutedEvent("Expanded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes true. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Expanded { add { AddHandler(ExpandedEvent, value); } remove { RemoveHandler(ExpandedEvent, value); } } ///becomes true. /// /// Called when /// Event arguments. protected virtual void OnExpanded(RoutedEventArgs e) { RaiseEvent(e); } ///becomes true. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent CollapsedEvent = EventManager.RegisterRoutedEvent("Collapsed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes false. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Collapsed { add { AddHandler(CollapsedEvent, value); } remove { RemoveHandler(CollapsedEvent, value); } } ///becomes false. /// /// Called when /// Event arguments. protected virtual void OnCollapsed(RoutedEventArgs e) { RaiseEvent(e); } ///becomes false. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes true. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Selected { add { AddHandler(SelectedEvent, value); } remove { RemoveHandler(SelectedEvent, value); } } ///becomes true. /// /// Called when /// Event arguments. protected virtual void OnSelected(RoutedEventArgs e) { RaiseEvent(e); } ///becomes true. /// Default implementation fires the event. /// /// Event fired when public static readonly RoutedEvent UnselectedEvent = EventManager.RegisterRoutedEvent("Unselected", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItem)); ///becomes false. /// /// Event fired when [Category("Behavior")] public event RoutedEventHandler Unselected { add { AddHandler(UnselectedEvent, value); } remove { RemoveHandler(UnselectedEvent, value); } } ///becomes false. /// /// Called when /// Event arguments. protected virtual void OnUnselected(RoutedEventArgs e) { RaiseEvent(e); } #endregion #region Internal Methods ///becomes false. /// Default implementation fires the event. /// /// TreeView keeps track of the size estimate; forward the call to it. /// ///double VirtualizingStackPanel.IProvideStackingSize.EstimatedContainerSize(bool isHorizontal) { TreeView parent = ParentTreeView; Size estimate = Size.Empty; if (parent != null) { estimate = ParentTreeView.CurrentContainerSizeEstimate; } return isHorizontal ? estimate.Width : estimate.Height; } /// /// Return the size of the header in the requested direction. /// /// ///double VirtualizingStackPanel.IProvideStackingSize.HeaderSize(bool isHorizontal) { UIElement header = null; ControlTemplate template = Template; if (template != null) { header = template.FindName("PART_Header", this) as UIElement; if (header != null) { return isHorizontal ? header.DesiredSize.Width : header.DesiredSize.Height; } } return 0d; } #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 ReadControlFlag(ControlBoolFlags.ContainsSelection); } set { WriteControlFlag(ControlBoolFlags.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 item = FindPreviousFocusableItem(); if (item != null) { if (item == ParentItemsControl && item == ParentTreeView) { return true; // Prevents KeyboardNavigation from focusing one of our children } return item.Focus(); } } return false; // Not handled } internal bool HandleDownKey() { if (AllowHandleKeyEvent(FocusNavigationDirection.Down)) { 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 = FindLastFocusableItem(item); if (lastItem != null) { return lastItem.Focus(); } return false; } internal bool FocusDown() { TreeViewItem item = FindNextFocusableItem(true); if (item != null) { return item.Focus(); } return false; } ////// Returns the next item in the TreeView hierarchy, regardless of depth. /// ///private TreeViewItem FindNextFocusableItem(bool walkIntoSubtree) { // // First walk into this item's subtree // if (walkIntoSubtree && IsExpanded && CanExpand) { TreeViewItem item = ItemContainerGenerator.ContainerFromIndex(0) as TreeViewItem; if (item != null) { if (item.IsEnabled) { return item; } else { return item.FindNextFocusableItem(false); } } } // // Otherwise go to the next sibling // ItemsControl parent = ParentItemsControl; if (parent != null) { TreeViewItem item; int index = parent.ItemContainerGenerator.IndexFromContainer(this); int count = parent.Items.Count; while (index < count) { // Find the next sibling index++; item = parent.ItemContainerGenerator.ContainerFromIndex(index) as TreeViewItem; if ((item != null) && item.IsEnabled) { return item; } } // This item has no next sibling, find the parent's next sibling item = parent as TreeViewItem; if (item != null) { return item.FindNextFocusableItem(false); } } return null; // Not handled } /// /// Returns the previous item in the TreeView hierarchy, regardless of depth. /// ///private ItemsControl FindPreviousFocusableItem() { 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) { TreeViewItem lastItem = FindLastFocusableItem(item); if (lastItem != null) { return lastItem; } } } return parent; } return null; } /// /// Returns the last focusable item in the given subtree. /// ///private static TreeViewItem FindLastFocusableItem(TreeViewItem item) { Debug.Assert(item.IsEnabled, "Only call FocusIntoItem with an enabled item"); TreeViewItem lastItem = null; // Find the last child in the subtree. int index = -1; TreeViewItem parent = null; while (item != null) { if (item.IsEnabled) { if (!item.IsExpanded || !item.CanExpand) { return item; } 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; } return null; } /// /// This should be PredictFocus but since UIElement.PredictFocus is sealed by FE we can't override it. /// TreeViewItem has its own code for deciding where focus should go. /// /// ///internal DependencyObject InternalPredictFocus(FocusNavigationDirection direction) { switch (direction) { case FocusNavigationDirection.Left: case FocusNavigationDirection.Up: return FindPreviousFocusableItem(); case FocusNavigationDirection.Right: case FocusNavigationDirection.Down: return FindNextFocusableItem(true); default: return null; } } 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 //dmitryt, 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(); } ////// We only override this to help with container estimation for virtualization /// /// ///protected override Size MeasureOverride(Size constraint) { Size desiredSize = base.MeasureOverride(constraint); if (IsVirtualizing && !IsExpanded && IsVisible) { TreeView parent = ParentTreeView; if (parent != null) { parent.RegisterContainerSize(IsLogicalHorizontal ? desiredSize.Width : desiredSize.Height); } } return desiredSize; } /// /// Send down the IsVirtualizing property if it's set on this element. /// /// /// protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { base.PrepareContainerForItemOverride(element, item); IsVirtualizingPropagationHelper(this, element); } // Synchronizes the value of the child's IsVirtualizing property with that of the parent's internal static void IsVirtualizingPropagationHelper(DependencyObject parent, DependencyObject element) { SynchronizeValue(VirtualizingStackPanel.IsVirtualizingProperty, parent, element); SynchronizeValue(VirtualizingStackPanel.VirtualizationModeProperty, parent, element); } private static void SynchronizeValue(DependencyProperty dp, DependencyObject parent, DependencyObject child) { if (IsDefaultValue(dp, parent)) { child.ClearValue(dp); } else { object value = parent.GetValue(dp); child.SetValue(dp, value); } } private static bool IsDefaultValue(DependencyProperty dp, DependencyObject element) { bool hasModifiers; return element.GetValueSource(dp, null, out hasModifiers) == BaseValueSourceInternal.Default; } ////// 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 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Soap.cs
- TemplateControlBuildProvider.cs
- InputScopeNameConverter.cs
- OutputWindow.cs
- HttpFileCollection.cs
- SingleObjectCollection.cs
- ClipboardData.cs
- PageAsyncTask.cs
- StreamWithDictionary.cs
- WindowsMenu.cs
- TypeContext.cs
- columnmapfactory.cs
- BindingMemberInfo.cs
- TraceInternal.cs
- BaseParser.cs
- DataGridViewRowConverter.cs
- FileUtil.cs
- UnsafeNativeMethods.cs
- DecoderNLS.cs
- TextEditorContextMenu.cs
- DataBoundLiteralControl.cs
- DefaultMemberAttribute.cs
- ActivityBindForm.Designer.cs
- ComponentCollection.cs
- StylusButtonEventArgs.cs
- EventDescriptor.cs
- X509Chain.cs
- DynamicMethod.cs
- HttpClientCertificate.cs
- DataStreamFromComStream.cs
- DbConnectionFactory.cs
- WriterOutput.cs
- ResXFileRef.cs
- ExpressionBindingCollection.cs
- WpfGeneratedKnownProperties.cs
- LogicalExpr.cs
- OSFeature.cs
- RowSpanVector.cs
- EventMemberCodeDomSerializer.cs
- ModelItemKeyValuePair.cs
- SingleSelectRootGridEntry.cs
- OperationCanceledException.cs
- XmlAnyElementAttribute.cs
- TriggerActionCollection.cs
- Persist.cs
- BinaryConverter.cs
- PolicyImporterElement.cs
- DnsPermission.cs
- PasswordPropertyTextAttribute.cs
- ConfigurationStrings.cs
- KerberosRequestorSecurityToken.cs
- Stack.cs
- FullTrustAssemblyCollection.cs
- CompModSwitches.cs
- FontEmbeddingManager.cs
- RoutingEndpointTrait.cs
- BindingExpressionUncommonField.cs
- NameScopePropertyAttribute.cs
- BuiltInPermissionSets.cs
- ComboBoxAutomationPeer.cs
- StateMachine.cs
- MaskInputRejectedEventArgs.cs
- TextServicesCompartmentContext.cs
- CheckBoxStandardAdapter.cs
- WebException.cs
- XMLUtil.cs
- ManagementDateTime.cs
- WindowsContainer.cs
- TargetFrameworkAttribute.cs
- SecurityResources.cs
- CommandExpr.cs
- RegionInfo.cs
- SqlFunctionAttribute.cs
- MatrixCamera.cs
- PropertyDescriptor.cs
- LoadRetryHandler.cs
- _ScatterGatherBuffers.cs
- PageContentAsyncResult.cs
- GridLength.cs
- Style.cs
- RemotingConfigParser.cs
- Slider.cs
- CustomErrorsSection.cs
- Token.cs
- SettingsProperty.cs
- MachineKeySection.cs
- _DisconnectOverlappedAsyncResult.cs
- ComponentChangingEvent.cs
- MissingSatelliteAssemblyException.cs
- NodeFunctions.cs
- UserNameSecurityTokenProvider.cs
- Util.cs
- ACE.cs
- FastEncoder.cs
- WebChannelFactory.cs
- Int64KeyFrameCollection.cs
- SystemIcons.cs
- CompareInfo.cs
- CorrelationManager.cs
- FunctionNode.cs