Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / FocusManager.cs / 1305600 / FocusManager.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Threading;
using System.Threading;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Security;
using System.Security.Permissions;
using MS.Internal.KnownBoxes;
namespace System.Windows.Input
{
///
/// FocusManager define attached property used for tracking the FocusedElement with a focus scope
///
public static class FocusManager
{
#region Public Events
///
/// GotFocus event
///
public static readonly RoutedEvent GotFocusEvent = EventManager.RegisterRoutedEvent("GotFocus", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FocusManager));
///
/// LostFocus event
///
public static readonly RoutedEvent LostFocusEvent = EventManager.RegisterRoutedEvent("LostFocus", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FocusManager));
#endregion Public Events
#region Public Properties
#region FocusedElement property
///
/// The DependencyProperty for the FocusedElement property. This internal property tracks IsActive
/// element ref inside TrackFocus
/// Default Value: null
///
public static readonly DependencyProperty FocusedElementProperty =
DependencyProperty.RegisterAttached(
"FocusedElement",
typeof(IInputElement),
typeof(FocusManager),
new PropertyMetadata(new PropertyChangedCallback(OnFocusedElementChanged)));
#endregion FocusedElement property
#region IsFocusScope Property
///
/// The DependencyProperty for the IsFocusScope property.
/// This property is used to mark the special containers (like Window, Menu) so they can
/// keep track of the FocusedElement element inside the container. Once focus is set
/// on the container - it is delegated to the FocusedElement element
/// Default Value: false
///
public static readonly DependencyProperty IsFocusScopeProperty
= DependencyProperty.RegisterAttached("IsFocusScope", typeof(bool), typeof(FocusManager),
new PropertyMetadata(BooleanBoxes.FalseBox));
#endregion IsFocusScope Property
#endregion
#region Public static methods
///
/// Return the property value of FocusedElement property.
///
///
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public static IInputElement GetFocusedElement(DependencyObject element)
{
return GetFocusedElement(element, false);
}
///
/// Return the property value of FocusedElement property. The return value is validated
/// to be in the subtree of element. If FocusedElement element is not a descendant of element this method return null
///
///
///
///
///
/// Critical: This code accesses PresentationSource.CriticalFromVisual which is critical
/// TreatAsSafe: This code does not expose it and simply uses it for determining if the FocusedElement is valid
///
[SecurityCritical, SecurityTreatAsSafe]
internal static IInputElement GetFocusedElement(DependencyObject element, bool validate)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
DependencyObject focusedElement = (DependencyObject) element.GetValue(FocusedElementProperty);
// Validate FocusedElement wrt to its FocusScope. If the two do not belong to the same PresentationSource
// then sever this link between them. The classic scenario for this is when an element with logical focus is
// dragged out into a floating widow. We want to prevent the MainWindow (focus scope) to point to the
// element in the floating window as its logical FocusedElement.
if (validate && focusedElement != null)
{
DependencyObject focusScope = element;
if (PresentationSource.CriticalFromVisual(focusScope) != PresentationSource.CriticalFromVisual(focusedElement))
{
SetFocusedElement(focusScope, null);
focusedElement = null;
}
}
return (IInputElement)focusedElement;
}
///
/// Set FocusedElement property for element.
///
///
///
public static void SetFocusedElement(DependencyObject element, IInputElement value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(FocusedElementProperty, value);
}
///
/// Writes the attached property IsFocusScope to the given element.
///
/// The element to which to write the attached property.
/// The property value to set
public static void SetIsFocusScope(DependencyObject element, bool value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(IsFocusScopeProperty, value);
}
///
/// Reads the attached property IsFocusScope from the given element.
///
/// The element from which to read the attached property.
/// The property's value.
public static bool GetIsFocusScope(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool)element.GetValue(IsFocusScopeProperty);
}
///
/// Find the closest visual ancestor that has IsFocusScope set to true
///
///
///
public static DependencyObject GetFocusScope(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return _GetFocusScope(element);
}
#endregion Public methods
#region private implementation
//
private static void OnFocusedElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IInputElement newFocusedElement = (IInputElement)e.NewValue;
DependencyObject oldVisual = (DependencyObject)e.OldValue;
DependencyObject newVisual = (DependencyObject)e.NewValue;
if (oldVisual != null)
{
oldVisual.ClearValue(UIElement.IsFocusedPropertyKey);
}
if (newVisual != null)
{
// set IsFocused on the element. The element may redirect Keyboard focus
// in response to this (e.g. Editable ComboBox redirects to the
// child TextBox), so detect whether this happens.
DependencyObject oldFocus = Keyboard.FocusedElement as DependencyObject;
newVisual.SetValue(UIElement.IsFocusedPropertyKey, BooleanBoxes.TrueBox);
DependencyObject newFocus = Keyboard.FocusedElement as DependencyObject;
// set the Keyboard focus to the new element, provided that
// a) the element didn't already set Keyboard focus
// b) Keyboard focus is not already on the new element
// c) the new element is within the same focus scope as the current
// holder (if any) of Keyboard focus
if (oldFocus == newFocus && newVisual != newFocus &&
(newFocus == null || GetRoot(newVisual) == GetRoot(newFocus)))
{
Keyboard.Focus(newFocusedElement);
}
}
/*
if (!_currentlyUpdatingTree)
{
_currentlyUpdatingTree = true;
IInputElement newFocusedElement = (IInputElement) newValue;
Visual oldVisual = GetNearestVisual(args.OldValue);
Visual newVisual = GetNearestVisual(args.NewValue);
if (oldVisual != null)
{
oldVisual.ClearValue(UIElement.IsFocusedPropertyKey);
// reverse-inherit: clear the property on all parents that aren't also in the
// new focused element ancestry
while (oldVisual != null)
{
oldVisual.ClearValue(FocusedElementProperty);
oldVisual = VisualTreeHelper.GetParent(oldVisual);
if ((oldVisual == newVisual) || oldVisual.IsAncestorOf(newVisual))
{
// only walk up until you reach a common parent -- the new value walk will take care of the rest
break;
}
}
}
if (newVisual != null)
{
newVisual.SetValue(UIElement.IsFocusedPropertyKey, BooleanBoxes.TrueBox);
// reverse-inherit: set the property on all parents
while (newVisual != null)
{
newVisual.SetValue(FocusedElementProperty, newFocusedElement);
newVisual = VisualTreeHelper.GetParent(newVisual);
}
// Set Keyboard focus to the element if not already focused && current focus is within the current focus scope
DependencyObject currentFocus = Keyboard.FocusedElement as DependencyObject;
if ((currentFocus == null) &&
(newVisual != currentFocus) &&
(GetRoot(newVisual) == GetRoot(currentFocus)))
{
Keyboard.Focus(newFocusedElement);
}
}
_currentlyUpdatingTree = false;
}
*/
}
/*
private static Visual GetNearestVisual(object value)
{
Visual visual = null;
if (value != null)
{
visual = value as Visual;
if (visual == null)
{
ContentElement ce = value as ContentElement;
if (ce != null)
{
visual = ce.GetUIParent() as Visual;
}
}
}
return visual;
}
*/
private static DependencyObject GetRoot(DependencyObject element)
{
if (element == null)
return null;
DependencyObject parent = null;
DependencyObject dependencyObject = element;
ContentElement ce = element as ContentElement;
if (ce != null)
dependencyObject = ce.GetUIParent();
while (dependencyObject != null)
{
parent = dependencyObject;
dependencyObject = VisualTreeHelper.GetParent(dependencyObject);
}
return parent;
}
// Walk up the parent chain to find the closest element with IsFocusScope=true
private static DependencyObject _GetFocusScope(DependencyObject d)
{
if (d == null)
return null;
if ((bool)d.GetValue(IsFocusScopeProperty))
return d;
// Step 1: Walk up the logical tree
UIElement uiElement = d as UIElement;
if (uiElement != null)
{
DependencyObject logicalParent = uiElement.GetUIParentCore();
if (logicalParent != null)
{
return GetFocusScope(logicalParent);
}
}
else
{
ContentElement ce = d as ContentElement;
if (ce != null)
{
DependencyObject logicalParent = ce.GetUIParent(true);
if (logicalParent != null)
{
return _GetFocusScope(logicalParent);
}
}
else
{
UIElement3D uiElement3D = d as UIElement3D;
if (uiElement3D != null)
{
DependencyObject logicalParent = uiElement3D.GetUIParentCore();
if (logicalParent != null)
{
return GetFocusScope(logicalParent);
}
}
}
}
// Step 2: Walk up the visual tree
if (d is Visual || d is Visual3D)
{
DependencyObject visualParent = VisualTreeHelper.GetParent(d);
if (visualParent != null)
{
return _GetFocusScope(visualParent);
}
}
// If visual and logical parent is null - then the element is implicit focus scope
return d;
}
#endregion private implementation
#region private data
private static readonly UncommonField IsFocusedElementSet = new UncommonField();
private static readonly UncommonField FocusedElementWeakCacheField = new UncommonField();
private static readonly UncommonField IsFocusedElementCacheValid = new UncommonField();
private static readonly UncommonField FocusedElementCache = new UncommonField();
// private static bool _currentlyUpdatingTree = false;
#endregion private data
}
}
// 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
- ValueTable.cs
- SoapIgnoreAttribute.cs
- ExtenderProviderService.cs
- MailBnfHelper.cs
- QuaternionRotation3D.cs
- ScrollPattern.cs
- ItemType.cs
- ListManagerBindingsCollection.cs
- XPathNavigator.cs
- DataPointer.cs
- SizeConverter.cs
- PartialTrustVisibleAssembly.cs
- DateTimeFormatInfoScanner.cs
- HtmlFormAdapter.cs
- ChangeConflicts.cs
- HistoryEventArgs.cs
- PropertyRecord.cs
- Label.cs
- ManagementObjectSearcher.cs
- SystemNetHelpers.cs
- Mouse.cs
- EmptyEnumerator.cs
- QueueSurrogate.cs
- StorageSetMapping.cs
- DataSourceHelper.cs
- TypeUnloadedException.cs
- ProfilePropertyNameValidator.cs
- TagPrefixCollection.cs
- TextEndOfSegment.cs
- WebException.cs
- BaseTemplateBuildProvider.cs
- ReferenceSchema.cs
- XmlDeclaration.cs
- ThemeDirectoryCompiler.cs
- KeyEvent.cs
- ListViewGroupItemCollection.cs
- UnsafeNativeMethods.cs
- MarkupCompilePass1.cs
- UnicastIPAddressInformationCollection.cs
- EmptyEnumerator.cs
- SaveFileDialogDesigner.cs
- TdsParser.cs
- FixedSOMPageElement.cs
- DataViewManagerListItemTypeDescriptor.cs
- SafeWaitHandle.cs
- XmlSchemaAttributeGroup.cs
- recordstatefactory.cs
- AppDomainUnloadedException.cs
- DataGridViewRowCancelEventArgs.cs
- CheckBoxRenderer.cs
- HtmlTableRowCollection.cs
- RMPublishingDialog.cs
- BindingManagerDataErrorEventArgs.cs
- LineGeometry.cs
- ListControlConvertEventArgs.cs
- Baml2006Reader.cs
- ECDsa.cs
- KeySplineConverter.cs
- HtmlElement.cs
- StringCollectionMarkupSerializer.cs
- AvTraceFormat.cs
- HostVisual.cs
- EditorAttribute.cs
- OwnerDrawPropertyBag.cs
- NamedPermissionSet.cs
- CFStream.cs
- WebServiceEnumData.cs
- Comparer.cs
- RichTextBox.cs
- Scheduling.cs
- DbParameterHelper.cs
- SecureConversationSecurityTokenParameters.cs
- URLMembershipCondition.cs
- MetafileHeaderWmf.cs
- EntityReference.cs
- SHA384Managed.cs
- TraceHandlerErrorFormatter.cs
- TagMapInfo.cs
- SchemaType.cs
- XPathSelfQuery.cs
- HtmlInputText.cs
- StrongNameKeyPair.cs
- XmlQualifiedName.cs
- FixUp.cs
- Bidi.cs
- SubMenuStyle.cs
- ProfileParameter.cs
- WindowsFont.cs
- VectorAnimation.cs
- BufferedStream.cs
- ManipulationBoundaryFeedbackEventArgs.cs
- DataGridTableCollection.cs
- RtfFormatStack.cs
- documentsequencetextcontainer.cs
- RegexCaptureCollection.cs
- PermissionToken.cs
- HotSpot.cs
- OpenTypeLayoutCache.cs
- ReferencedCollectionType.cs
- CredentialCache.cs