using System.Diagnostics; using System.Windows.Controls.Primitives; using System.Windows.Input; namespace Melskin.Controls; /// /// A hyperlink button. /// public class Hyperlink : ButtonBase { #region Properties /// /// 已经浏览过的依赖属性。 /// public bool IsVisited { get { return (bool)GetValue(IsVisitedProperty); } // 外部无法直接赋值,只能读取 private set { SetValue(IsVisitedPropertyKey, value); } } /// /// 定义私有的 Key:这是“写入权限”的钥匙,只有在这个类内部才能拿到 /// public static readonly DependencyProperty IsVisitedProperty = IsVisitedPropertyKey.DependencyProperty; /// /// 表示已经浏览过的依赖属性。 /// public static readonly DependencyPropertyKey IsVisitedPropertyKey = DependencyProperty.RegisterReadOnly(nameof(IsVisited), typeof(bool), typeof(Hyperlink), new PropertyMetadata(false)); /// /// 外部调用此方法来将超链接标记为已访问。 /// public void MarkAsVisited() { SetValue(IsVisitedPropertyKey, true); } /// /// 表示超链接地址的依赖属性。 /// public static readonly DependencyProperty NavigateUriProperty = DependencyProperty.Register(nameof(NavigateUri), typeof(string), typeof(Hyperlink), new PropertyMetadata(string.Empty)); /// /// Gets or sets the uri of hyperlinks. /// public string NavigateUri { get => (string)GetValue(NavigateUriProperty); set => SetValue(NavigateUriProperty, value); } #endregion #region Constructors static Hyperlink() { DefaultStyleKeyProperty.OverrideMetadata(typeof(Hyperlink), new FrameworkPropertyMetadata(typeof(Hyperlink))); } #endregion /// /// 点击后的事件 /// /// protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (string.IsNullOrEmpty(NavigateUri)) return; try { // 1. 打开网页 Process.Start(new ProcessStartInfo(NavigateUri) { UseShellExecute = true }); // 2. 改变自身状态(这就是你作为控件的“记忆”) SetValue(IsVisitedPropertyKey, true); } catch { // 忽略无效链接异常 } } }