Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Documents / Hyperlink.cs / 3 / Hyperlink.cs
//---------------------------------------------------------------------------- // File: Hyperlink.cs // // Description: // Implementation of Underline element. // // Copyright (C) 2004 by Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; using System.ComponentModel; using System.Windows; // DependencyID etc. using System.Windows.Automation.Peers; using System.Windows.Controls; // using System.Windows.Input; using System.Windows.Navigation; using System.Threading; using System.Windows.Markup; // IUriContext using System.Security; using System.Security.Permissions; using MS.Internal; using MS.Internal.AppModel; using MS.Internal.Utility; using MS.Internal.PresentationFramework; // SecurityHelper namespace System.Windows.Documents { ////// Implements a Hyperlink element /// [UIPermissionAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] [TextElementEditingBehaviorAttribute(IsMergeable = false, IsTypographicOnly = false)] public class Hyperlink : Span, ICommandSource, IUriContext { //------------------------------------------------------------------- // // Constructors // //--------------------------------------------------------------------- #region Constructors // // Static Ctor to create default style sheet // static Hyperlink() { DefaultStyleKeyProperty.OverrideMetadata(typeof(Hyperlink), new FrameworkPropertyMetadata(typeof(Hyperlink))); _dType = DependencyObjectType.FromSystemTypeInternal(typeof(Hyperlink)); FocusableProperty.OverrideMetadata(typeof(Hyperlink), new FrameworkPropertyMetadata(true)); EventManager.RegisterClassHandler(typeof(Hyperlink), Mouse.QueryCursorEvent, new QueryCursorEventHandler(OnQueryCursor)); } ////// Initializes a new instance of Hyperlink element. /// ////// To become fully functional this element requires at least one other Inline element /// as its child, typically Run with some text. /// public Hyperlink() : base() { } ////// Initializes a new instance of Hyperlink element and adds a given Inline element as its first child. /// /// /// Inline element added as an initial child to this Hyperlink element /// public Hyperlink(Inline childInline) : base(childInline) { } ////// Creates a new Span instance. /// /// /// Optional child Inline for the new Span. May be null. /// /// /// Optional position at which to insert the new Span. May be null. /// public Hyperlink(Inline childInline, TextPointer insertionPosition) : base(childInline, insertionPosition) { } ////// Creates a new Hyperlink instance covering existing content. /// /// /// Start position of the new Hyperlink. /// /// /// End position of the new Hyperlink. /// ////// start and end must both be parented by the same Paragraph, otherwise /// the method will raise an ArgumentException. /// public Hyperlink(TextPointer start, TextPointer end) : base(start, end) { // After inserting this Hyperlink, we need to extract any child Hyperlinks. TextPointer navigator = this.ContentStart.CreatePointer(); TextPointer stop = this.ContentEnd; while (navigator.CompareTo(stop) < 0) { Hyperlink hyperlink = navigator.GetAdjacentElement(LogicalDirection.Forward) as Hyperlink; if (hyperlink != null) { hyperlink.Reposition(null, null); } else { navigator.MoveToNextContextPosition(LogicalDirection.Forward); } } } #endregion Constructors //-------------------------------------------------------------------- // // Public Methods // //--------------------------------------------------------------------- #region Public Methods ////// This method does exactly the same operation as clicking the Hyperlink with the mouse. /// public void DoClick() { OnClick(); } #region ICommandSource ////// The DependencyProperty for RoutedCommand /// public static readonly DependencyProperty CommandProperty = DependencyProperty.Register( "Command", typeof(ICommand), typeof(Hyperlink), new FrameworkPropertyMetadata((ICommand)null, new PropertyChangedCallback(OnCommandChanged))); ////// Get or set the Command property /// [Bindable(true), Category("Action")] [Localizability(LocalizationCategory.NeverLocalize)] public ICommand Command { get { return (ICommand)GetValue(CommandProperty); } set { SetValue(CommandProperty, value); } } private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Hyperlink h = (Hyperlink)d; h.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue); } private void OnCommandChanged(ICommand oldCommand, ICommand newCommand) { if (oldCommand != null) { UnhookCommand(oldCommand); } if (newCommand != null) { HookCommand(newCommand); } } private void UnhookCommand(ICommand command) { EventHandler handler = CanExecuteChangedHandler.GetValue(this); if (handler != null) { command.CanExecuteChanged -= handler; CanExecuteChangedHandler.ClearValue(this); } UpdateCanExecute(); } private void HookCommand(ICommand command) { EventHandler handler = new EventHandler(OnCanExecuteChanged); CanExecuteChangedHandler.SetValue(this, handler); command.CanExecuteChanged += handler; UpdateCanExecute(); } private void OnCanExecuteChanged(object sender, EventArgs e) { UpdateCanExecute(); } private void UpdateCanExecute() { if (Command != null) { CanExecute = MS.Internal.Commands.CommandHelpers.CanExecuteCommandSource(this); } else { CanExecute = true; } } private bool CanExecute { get { return _canExecute; } set { if (_canExecute != value) { _canExecute = value; CoerceValue(IsEnabledProperty); } } } // Returns true when this Hyperlink is hosted by an enabled // TextEditor (eg, within a RichTextBox). private bool IsEditable { get { return (this.TextContainer.TextSelection != null && !this.TextContainer.TextSelection.TextEditor.IsReadOnly); } } ////// Fetches the value of the IsEnabled property /// ////// The reason this property is overridden is so that Hyperlink /// can infuse the value for CanExecute into it. /// protected override bool IsEnabledCore { get { return base.IsEnabledCore && CanExecute; } } ////// The DependencyProperty for the CommandParameter /// public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register( "CommandParameter", typeof(object), typeof(Hyperlink), new FrameworkPropertyMetadata((object)null)); ////// Reflects the parameter to pass to the CommandProperty upon execution. /// [Bindable(true), Category("Action")] [Localizability(LocalizationCategory.NeverLocalize)] public object CommandParameter { get { return GetValue(CommandParameterProperty); } set { SetValue(CommandParameterProperty, value); } } ////// The DependencyProperty for Target property /// Flags: None /// Default Value: null /// public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register( "CommandTarget", typeof(IInputElement), typeof(Hyperlink), new FrameworkPropertyMetadata((IInputElement)null)); ////// The target element on which to fire the command. /// [Bindable(true), Category("Action")] public IInputElement CommandTarget { get { return (IInputElement)GetValue(CommandTargetProperty); } set { SetValue(CommandTargetProperty, value); } } #endregion #endregion Public Methods //-------------------------------------------------------------------- // // Public Properties // //---------------------------------------------------------------------- #region Public Properties ////// Contains the target URI to navigate when hyperlink is clicked /// [CommonDependencyProperty] public static readonly DependencyProperty NavigateUriProperty = DependencyProperty.Register("NavigateUri", typeof(Uri), typeof(Hyperlink), new FrameworkPropertyMetadata((Uri)null)); ////// Provide public access to NavigateUriProperty property. Content the URI to navigate. /// [Bindable(true), CustomCategory("Navigation")] [Localizability(LocalizationCategory.Hyperlink)] public Uri NavigateUri { get { return GetValue(NavigateUriProperty) as Uri; } set { SetValue(NavigateUriProperty, value); } } ////// Contains the target window to navigate when hyperlink is clicked /// public static readonly DependencyProperty TargetNameProperty = DependencyProperty.Register("TargetName", typeof(String), typeof(Hyperlink), new FrameworkPropertyMetadata(string.Empty)); ////// Provide public access to TargetNameProperty property. The target window to navigate. /// [Bindable(true), CustomCategory("Navigation")] [Localizability( LocalizationCategory.None, Modifiability = Modifiability.Unmodifiable) ] public string TargetName { get { return GetValue(TargetNameProperty) as string; } set { SetValue(TargetNameProperty, value); } } #endregion Public Properties //------------------------------------------------------------------- // // Public Events // //---------------------------------------------------------------------- #region Public Events // ** ////// Navigate Event /// public static readonly RoutedEvent RequestNavigateEvent = EventManager.RegisterRoutedEvent( "RequestNavigate", RoutingStrategy.Bubble, typeof(RequestNavigateEventHandler), typeof(Hyperlink)); ////// Add / Remove RequestNavigateEvent handler /// public event RequestNavigateEventHandler RequestNavigate { add { AddHandler(RequestNavigateEvent, value); } remove { RemoveHandler(RequestNavigateEvent, value); } } ////// Event correspond to left mouse button click /// public static readonly RoutedEvent ClickEvent = System.Windows.Controls.Primitives.ButtonBase.ClickEvent.AddOwner(typeof(Hyperlink)); ////// Add / Remove ClickEvent handler /// [Category("Behavior")] public event RoutedEventHandler Click { add { AddHandler(ClickEvent, value); } remove { RemoveHandler(ClickEvent, value); } } ////// StatusBar event /// internal static readonly RoutedEvent RequestSetStatusBarEvent = EventManager.RegisterRoutedEvent( "RequestSetStatusBar", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Hyperlink)); #endregion Public Events //------------------------------------------------------------------- // // Protected Methods // //--------------------------------------------------------------------- #region Protected Methods ////// This is the method that responds to the KeyDown event. /// /// ////// Critical - asserts UserInitatedNavigationPermisison. /// /// TreatAsSafe - assert is used to enable "safe" navigation only. /// we consider this safe as we only assert if this is a userInitiated action. /// The UserInitiated bit is set inside of the InputManager - and tracked via critical. /// /// Note that we LinkDemand and InheritanceDemand for calling OnKeyDown. /// To defend against someone caching the trusted event args - and playing it back to us. /// [SecurityCritical, SecurityTreatAsSafe] [UIPermissionAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] //we get a compiler warning that a similar LinkDemand should exist on the base class (ContentElement) //but we don't want or need that. The base class doesn't cause navigation to happen so it's safe to //call programatically. #pragma warning disable 0688 [UIPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] protected override void OnKeyDown(KeyEventArgs e) { if (e.RoutedEvent == Keyboard.KeyDownEvent && e.Key == Key.Enter) { if (e.UserInitiated) { CodeAccessPermission perm = SecurityHelper.CreateUserInitiatedNavigationPermission(); perm.Assert(); } try { e.Handled = true; OnClick(); } finally { if (e.UserInitiated) { CodeAccessPermission.RevertAssert(); } } } else { base.OnKeyDown(e); } } #pragma warning restore 0688 ////// This is the method that responds to the MouseButtonEvent event. /// /// Event arguments protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (IsEnabled && (!IsEditable || ((Keyboard.Modifiers & ModifierKeys.Control) != 0))) { // Hyperlink should take focus when left mouse button is clicked on it // This is consistent with all ButtonBase controls and current Win32 behavior Focus(); // It is possible that the mouse state could have changed during all of // the call-outs that have happened so far. if (e.ButtonState == MouseButtonState.Pressed) { // Capture the mouse, and make sure we got it. // WARNING: callout CaptureMouse(); if (IsMouseCaptured) { // Though we have already checked this state, our call to CaptureMouse // could also end up changing the state, so we check it again. // // if (e.ButtonState == MouseButtonState.Pressed) { _isPressed = true; } else { // Release capture since we decided not to press the button. ReleaseMouseCapture(); } } } e.Handled = true; } } ////// This is the method that responds to the MouseButtonEvent event. /// /// Event arguments ////// Critical - asserts UserInitatedNavigationPermisison. /// /// TreatAsSafe - assert is used to enable "safe" navigation only. /// we consider this safe as we only assert if this is a userInitiated action. /// The UserInitiated bit is set inside of the InputManager - and tracked via critical. /// /// Note that we LinkDemand and InheritanceDemand for calling OnMouseLeftButtonUp. /// To defend against someone caching the trusted event args - and playing it back to us. /// [SecurityCritical, SecurityTreatAsSafe ] [UIPermissionAttribute(SecurityAction.InheritanceDemand , Unrestricted=true)] //we get a compiler warning that a similar LinkDemand should exist on the base class (ContentElement) //but we don't want or need that. The base class doesn't cause navigation to happen so it's safe to //call programatically. #pragma warning disable 0688 [UIPermissionAttribute(SecurityAction.LinkDemand, Unrestricted = true)] protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { base.OnMouseLeftButtonUp(e); if (IsMouseCaptured) { ReleaseMouseCapture(); } // // if (_isPressed) { _isPressed = false; // Make sure we're mousing up over the hyperlink if (IsMouseOver) { bool assertCodeAccessPermission = e.UserInitiated && (e.RoutedEvent == UIElement.MouseLeftButtonUpEvent) && (e.ChangedButton == MouseButton.Left); if (assertCodeAccessPermission) { CodeAccessPermission perm = SecurityHelper.CreateUserInitiatedNavigationPermission(); perm.Assert(); } try { OnClick(); } finally { if (assertCodeAccessPermission) { CodeAccessPermission.RevertAssert(); } } } } e.Handled = true; } #pragma warning restore 0688 ////// Fire the event to change the status bar. /// protected override void OnMouseEnter(MouseEventArgs e) { Uri uri = NavigateUri; if (uri != null) { RequestSetStatusBarEventArgs args = new RequestSetStatusBarEventArgs(BindUriHelper.UriToString(uri)); RaiseEvent(args); } } ////// Set the status bar text back to empty /// protected override void OnMouseLeave(MouseEventArgs e) { RequestSetStatusBarEventArgs args = new RequestSetStatusBarEventArgs(String.Empty); RaiseEvent(args); } ////// Navigate to URI specified in NavigateUri property and mark the hyperlink as visited /// ///Some forms of navigation are not allowed in the internet zone. /// As such there are cases where this API will demand for fulltrust /// ////// Demands unrestricted UI permssion. /// Asserted in the InputManager when the command is userinitiated. /// protected virtual void OnClick() { if (AutomationPeer.ListenerExists(AutomationEvents.InvokePatternOnInvoked)) { AutomationPeer peer = ContentElementAutomationPeer.CreatePeerForElement(this); if (peer != null) peer.RaiseAutomationEvent(AutomationEvents.InvokePatternOnInvoked); } Uri uri = NavigateUri; if ((uri != null)) { // RequestNavigateEventArgs navigateArgs = new RequestNavigateEventArgs(uri, TargetName); navigateArgs.Source=this; RaiseEvent(navigateArgs); if (navigateArgs.Handled) { // The browser's status bar should be cleared. Otherwise it will still show the // hyperlink address after navigation has completed. RequestSetStatusBarEventArgs args = new RequestSetStatusBarEventArgs(String.Empty); RaiseEvent(args); } } RaiseEvent(new RoutedEventArgs(Hyperlink.ClickEvent, this)); MS.Internal.Commands.CommandHelpers.ExecuteCommandSource(this); } // // This property // 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject // 2. This is a performance optimization // internal override int EffectiveValuesInitialSize { get { return 19; } } ////// Creates AutomationPeer ( protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() { return new System.Windows.Automation.Peers.HyperlinkAutomationPeer(this); } #endregion Protected Methods #region IUriContext implementation ///) /// /// IUriContext interface is implemented by Hyperlink element so that it /// can hold on to the base URI used by parser. /// The base URI is needed to resolve NavigateUri property /// ///Base Uri Uri IUriContext.BaseUri { get { return BaseUri; } set { BaseUri = value; } } ////// Implementation for BaseUri /// protected virtual Uri BaseUri { get { return (Uri)GetValue(BaseUriHelper.BaseUriProperty); } set { SetValue(BaseUriHelper.BaseUriProperty, value); } } #endregion IUriContext implementation //------------------------------------------------------------------- // // Internal Properties // //---------------------------------------------------------------------- #region Internal Properties ////// The content spanned by this Hyperlink represented as plain text. /// [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] internal string Text { get { return TextRangeBase.GetTextInternal(this.ContentStart, this.ContentEnd); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //---------------------------------------------------------------------- #region Private Methods // QueryCursorEvent callback. // If this Hyperlink is editable, use the editor cursor unless // the control key is down. private static void OnQueryCursor(object sender, QueryCursorEventArgs e) { Hyperlink link = (Hyperlink)sender; if (link.IsEnabled && link.IsEditable) { if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) { e.Cursor = link.TextContainer.TextSelection.TextEditor._cursor; e.Handled = true; } } } #endregion Private Methods //-------------------------------------------------------------------- // // Private Fields // //--------------------------------------------------------------------- #region Private Fields bool _isPressed; private bool _canExecute = true; private static readonly UncommonFieldCanExecuteChangedHandler = new UncommonField (); #endregion Private Fields #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 } } // 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
- MetaTableHelper.cs
- AnnotationResourceChangedEventArgs.cs
- wmiprovider.cs
- ContentValidator.cs
- LambdaCompiler.Address.cs
- DynamicUpdateCommand.cs
- PageCodeDomTreeGenerator.cs
- CssClassPropertyAttribute.cs
- MultilineStringConverter.cs
- HttpHandlerAction.cs
- IImplicitResourceProvider.cs
- FilteredDataSetHelper.cs
- DataGridViewDataErrorEventArgs.cs
- BooleanAnimationBase.cs
- CommandField.cs
- WmlImageAdapter.cs
- GridViewRowPresenterBase.cs
- Package.cs
- ViewStateException.cs
- DataGridAutoFormat.cs
- smtppermission.cs
- ViewSimplifier.cs
- ToolStripLocationCancelEventArgs.cs
- ConstraintConverter.cs
- RuntimeIdentifierPropertyAttribute.cs
- RecordsAffectedEventArgs.cs
- ContentWrapperAttribute.cs
- ProxyGenerationError.cs
- ProviderIncompatibleException.cs
- DeclarativeCatalogPart.cs
- TemplatedEditableDesignerRegion.cs
- FileDialog.cs
- DependencyObjectType.cs
- PocoPropertyAccessorStrategy.cs
- complextypematerializer.cs
- XmlPreloadedResolver.cs
- ResourcesBuildProvider.cs
- Int16Converter.cs
- HtmlTableCell.cs
- XslTransform.cs
- versioninfo.cs
- WrapperEqualityComparer.cs
- TypePropertyEditor.cs
- DataGridViewHeaderCell.cs
- SessionParameter.cs
- TreeNodeCollection.cs
- BigIntegerStorage.cs
- RegexStringValidatorAttribute.cs
- ThemeableAttribute.cs
- SmiSettersStream.cs
- ExceptionHandler.cs
- tooltip.cs
- PictureBox.cs
- EntitySqlQueryCacheEntry.cs
- ImageSource.cs
- FormViewPagerRow.cs
- PackagingUtilities.cs
- FixedTextSelectionProcessor.cs
- ConnectionProviderAttribute.cs
- HTMLTagNameToTypeMapper.cs
- BaseTypeViewSchema.cs
- RelationshipEndCollection.cs
- UnsafeNativeMethods.cs
- WebReferencesBuildProvider.cs
- ComboBoxAutomationPeer.cs
- Point3DAnimationBase.cs
- StdValidatorsAndConverters.cs
- PropertyMapper.cs
- NavigationEventArgs.cs
- XmlSerializerOperationGenerator.cs
- SingleTagSectionHandler.cs
- EditingScope.cs
- StatusBarDrawItemEvent.cs
- TrackingSection.cs
- CodeDefaultValueExpression.cs
- BinaryFormatterWriter.cs
- TrackingAnnotationCollection.cs
- StreamResourceInfo.cs
- SQLDouble.cs
- SqlBulkCopy.cs
- RepeaterCommandEventArgs.cs
- FixUpCollection.cs
- TableSectionStyle.cs
- SchemaComplexType.cs
- ObjectListCommand.cs
- X500Name.cs
- TextCollapsingProperties.cs
- PartManifestEntry.cs
- HeaderedContentControl.cs
- DbConnectionPoolGroup.cs
- CqlIdentifiers.cs
- FilteredXmlReader.cs
- ItemAutomationPeer.cs
- WebSysDisplayNameAttribute.cs
- TextEffectResolver.cs
- GridViewDeletedEventArgs.cs
- TextRangeEditTables.cs
- _OSSOCK.cs
- ConfigXmlElement.cs
- ScrollItemProviderWrapper.cs