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
- AttributeUsageAttribute.cs
- DiscoveryDocument.cs
- ButtonBase.cs
- XamlFilter.cs
- ColorInterpolationModeValidation.cs
- TCPClient.cs
- LinkButton.cs
- ListView.cs
- XmlSerializationGeneratedCode.cs
- safesecurityhelperavalon.cs
- WebEvents.cs
- XmlDeclaration.cs
- HtmlInputText.cs
- NativeCppClassAttribute.cs
- BaseServiceProvider.cs
- ResourceIDHelper.cs
- DuplicateDetector.cs
- DataServiceClientException.cs
- SqlExpander.cs
- XmlSchemaObject.cs
- ClientConvert.cs
- AddInController.cs
- CacheChildrenQuery.cs
- BasicViewGenerator.cs
- CanExecuteRoutedEventArgs.cs
- XmlValidatingReaderImpl.cs
- ControlsConfig.cs
- SessionConnectionReader.cs
- CaseExpr.cs
- CompilerParameters.cs
- ConstraintEnumerator.cs
- ModuleConfigurationInfo.cs
- ColumnReorderedEventArgs.cs
- StringHandle.cs
- ProgressiveCrcCalculatingStream.cs
- BamlLocalizationDictionary.cs
- ComponentCollection.cs
- AttributeTableBuilder.cs
- ProxyGenerationError.cs
- XmlWellformedWriter.cs
- DataBinding.cs
- GridViewPageEventArgs.cs
- CapabilitiesPattern.cs
- XmlWriterTraceListener.cs
- RegexTree.cs
- ImportDesigner.xaml.cs
- DataViewSetting.cs
- InstanceDescriptor.cs
- ListControlBuilder.cs
- mactripleDES.cs
- RepeaterItemCollection.cs
- WindowsButton.cs
- Trace.cs
- XmlConvert.cs
- FlowDocumentReader.cs
- WindowsComboBox.cs
- RegistrySecurity.cs
- Figure.cs
- LoginUtil.cs
- LineUtil.cs
- OletxTransactionManager.cs
- ParameterCollection.cs
- XmlSerializableServices.cs
- MdiWindowListStrip.cs
- WebEventCodes.cs
- CmsInterop.cs
- InvokePattern.cs
- ListGeneralPage.cs
- ScriptResourceInfo.cs
- NullableFloatMinMaxAggregationOperator.cs
- BitStack.cs
- Panel.cs
- DBSqlParserTable.cs
- RelatedImageListAttribute.cs
- StateRuntime.cs
- GeometryHitTestParameters.cs
- SelectQueryOperator.cs
- Point3DAnimation.cs
- IdentityModelStringsVersion1.cs
- ToolStripPanelRow.cs
- TypeDefinition.cs
- IgnorePropertiesAttribute.cs
- MdiWindowListItemConverter.cs
- MasterPageParser.cs
- RequestStatusBarUpdateEventArgs.cs
- Pen.cs
- ColumnResult.cs
- ErrorFormatter.cs
- ProgressBarBrushConverter.cs
- RbTree.cs
- WindowsButton.cs
- AssociationTypeEmitter.cs
- JumpItem.cs
- ConfigurationSettings.cs
- ActionMismatchAddressingException.cs
- FocusChangedEventArgs.cs
- LicenseProviderAttribute.cs
- BamlRecordWriter.cs
- TemplateXamlParser.cs
- __ComObject.cs