• wpf,能够复制文字 及自动识别URL超链接的TextBlock


    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    
    namespace SelectableTextBlock
    {
        public class TextBlockSelect : TextBlock
        {
              TextPointer startpoz;
            TextPointer endpoz;
            MenuItem copyMenu;
            MenuItem selectAllMenu;
    
            public TextRange Selection { get; private set; }
            public bool HasSelection
            {
                get { return Selection != null && !Selection.IsEmpty; }
            }
    
            #region SelectionBrush
    
            public static readonly DependencyProperty SelectionBrushProperty =
                DependencyProperty.Register("SelectionBrush", typeof(Brush), typeof(TextBlockSelect),
                    new FrameworkPropertyMetadata(Brushes.Orange));
    
            public Brush SelectionBrush
            {
                get { return (Brush)GetValue(SelectionBrushProperty); }
                set { SetValue(SelectionBrushProperty, value); }
            }
    
            #endregion
    
            public static readonly DependencyProperty Text2Property =
        DependencyProperty.Register("Text2", typeof(string), typeof(TextBlockSelect),
            new FrameworkPropertyMetadata(new PropertyChangedCallback(OnText2PropertyChanged)));
    
            public string Text2
            {
                get { return (string)GetValue(Text2Property); }
                set { SetValue(Text2Property, value); }
            }
    
            static void OnText2PropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
            {
                if (sender != null && sender is TextBlockSelect)
                {
                    TextBlockSelect view = (TextBlockSelect)sender;
                    if (args != null && args.NewValue != null)
                    {
                        string value = args.NewValue.ToString();
                        if (string.IsNullOrWhiteSpace(value))
                        {
                            view.Text = "";
                            view.Inlines.Clear();
                        }
                        else
                        {
                            view.AddInlines(value);
                        }
                    }
                    else
                    {
                        view.Text = "";
                        view.Inlines.Clear();
                    }
                }
            }
    
            static void link_Click(object sender, RoutedEventArgs e)
            {
                Hyperlink link = sender as Hyperlink;
                Process.Start(new ProcessStartInfo(link.NavigateUri.AbsoluteUri));
                //throw new NotImplementedException();
            }
    
            public void AddInlines(string value)
            {
                Regex urlregex = new Regex(@"((http|ftp|https)://)(([a-zA-Z0-9._-]+.[a-zA-Z]{2,6})|([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9&%_./-~-]*)?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
                var ss = urlregex.Matches(value);
                List<Tuple<int, int, string>> urlList = new List<Tuple<int, int, string>>();
                foreach (Match item in ss)
                {
                    Tuple<int, int, string> urlIndex = new Tuple<int, int, string>(value.IndexOf(item.Value), item.Value.Length, item.Value);
                    urlList.Add(urlIndex);
                }
    
                if (urlList.Count > 0)
                {
                    //urlList.Sort();
                    for (int i = 0; i < urlList.Count; i++)
                    {
                        if (i == 0)
                        {
                            string startValue = value.Substring(0, urlList[0].Item1);
                            if (string.IsNullOrEmpty(startValue))
                                startValue = " ";
                            this.Inlines.Add(new Run() { Text = startValue });
    
                            AddHyperlink(urlList[0].Item3);
                        }
                        else
                        {
                            int stratIndex = urlList[i - 1].Item1 + urlList[i - 1].Item2;
                            this.Inlines.Add(new Run() { Text = value.Substring(stratIndex, urlList[i].Item1 - stratIndex) });
    
                            AddHyperlink(urlList[i].Item3);
                        }
    
                        if (i == urlList.Count - 1)
                        {
                            string endValue = value.Substring(urlList[i].Item1 + urlList[i].Item2);
                            if (string.IsNullOrEmpty(endValue))
                                endValue = " ";
                            this.Inlines.Add(new Run() { Text = endValue });
                        }
                    }
                }
                else
                {
                    this.Inlines.Clear();
                    this.Text = value;
                }
            }
    
            private void AddHyperlink(string value)
            {
                try
                {
                    Hyperlink link = new Hyperlink();
                    link.NavigateUri = new Uri(value);
                    link.Click += link_Click;
                    link.Inlines.Add(new Run() { Text = value });
                    this.Inlines.Add(link);
                }
                catch {
                    this.Inlines.Add(new Run() { Text = value });
                }
            }
    
            public TextBlockSelect()
            {
                Focusable = true;
                //InitMenu();
            }
    
            void InitMenu()
            {
                var contextMenu = new ContextMenu();
                ContextMenu = contextMenu;
    
                copyMenu = new MenuItem();
                copyMenu.Header = "复制";
                copyMenu.InputGestureText = "Ctrl + C";
                copyMenu.Click += (ss, ee) =>
                {
                    Copy();
                };
                contextMenu.Items.Add(copyMenu);
    
                selectAllMenu = new MenuItem();
                selectAllMenu.Header = "全选";
                selectAllMenu.InputGestureText = "Ctrl + A";
                selectAllMenu.Click += (ss, ee) =>
                {
                    SelectAll();
                };
                contextMenu.Items.Add(selectAllMenu);
    
                ContextMenuOpening += contextMenu_ContextMenuOpening;
            }
    
            void contextMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
            {
                copyMenu.IsEnabled = HasSelection;
            }
            protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
            {
                Keyboard.Focus(this);
                ReleaseMouseCapture();
                base.OnMouseLeftButtonUp(e);
            }
    
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                var point = e.GetPosition(this);
                startpoz = GetPositionFromPoint(point, true);
                CaptureMouse();
                base.OnMouseLeftButtonDown(e);
            }
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (IsMouseCaptured)
                {
                    var point = e.GetPosition(this);
                    endpoz = GetPositionFromPoint(point, true);
    
                    ClearSelection();
                    Selection = new TextRange(startpoz, endpoz);
                    Selection.ApplyPropertyValue(TextElement.BackgroundProperty, SelectionBrush);
                    CommandManager.InvalidateRequerySuggested();
    
                    OnSelectionChanged(EventArgs.Empty);
                }
    
                base.OnMouseMove(e);
            }
    
            protected override void OnKeyUp(KeyEventArgs e)
            {
                if (Keyboard.Modifiers == ModifierKeys.Control)
                {
                    if (e.Key == Key.C)
                        Copy();
                    else if (e.Key == Key.A)
                        SelectAll();
                }
    
                base.OnKeyUp(e);
            }
    
            protected override void OnLostFocus(RoutedEventArgs e)
            {
                ClearSelection();
                //base.OnLostFocus(e);
            }
    
            public bool Copy()
            {
                if (HasSelection)
                {
                    Clipboard.SetDataObject(Selection.Text);
                    return true;
                }
                return false;
            }
    
            public void ClearSelection()
            {
                var contentRange = new TextRange(ContentStart, ContentEnd);
                contentRange.ApplyPropertyValue(TextElement.BackgroundProperty, null);
                Selection = null;
            }
    
            public void SelectAll()
            {
                Selection = new TextRange(ContentStart, ContentEnd);
                Selection.ApplyPropertyValue(TextElement.BackgroundProperty, SelectionBrush);
            }
    
            public event EventHandler SelectionChanged;
    
            protected virtual void OnSelectionChanged(EventArgs e)
            {
                var handler = this.SelectionChanged;
                if (handler != null)
                    handler(this, e);
            }
        }
    
    
    }


      在 WPF: 可以点击选择和复制文本的TextBlock 的基础上添加了对Url的识别。

  • 相关阅读:
    错误滚动条eclipse快速定位到错误处
    路径原因linux下tomcat无法启动
    提示命令命令行将U盘文件系统转换成ntfs
    客户传真第四部分 个人理财风险防范8.当心银行汇款引发的诈骗
    请求错误[Python]网络爬虫(三):异常的处理和HTTP状态码的分类
    范围元【2013 GDCPC】有为杯 广东ACM省赛小总结
    编程程序国外程序员的BASIC情结——我的编程生涯始于BASIC
    执行取消利用timer实现的倒计时
    文件分析IDA反汇编/反编译静态分析iOS模拟器程序(二)加载文件与保存数据库
    安全业务第四部分 个人理财风险防范9.取款也要加小心
  • 原文地址:https://www.cnblogs.com/m7777/p/6233028.html
Copyright © 2020-2023  润新知