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 > )
{
//urlList.Sort();
for (int i = ; i < urlList.Count; i++)
{
if (i == )
{
string startValue = value.Substring(, urlList[].Item1);
if (string.IsNullOrEmpty(startValue))
startValue = " ";
this.Inlines.Add(new Run() { Text = startValue }); AddHyperlink(urlList[].Item3);
}
else
{
int stratIndex = urlList[i - ].Item1 + urlList[i - ].Item2;
this.Inlines.Add(new Run() { Text = value.Substring(stratIndex, urlList[i].Item1 - stratIndex) }); AddHyperlink(urlList[i].Item3);
} if (i == urlList.Count - )
{
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的识别。

wpf,能够复制文字 及自动识别URL超链接的TextBlock的更多相关文章

  1. WPF模拟探照灯文字

    原文:WPF模拟探照灯文字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1835936 ...

  2. js复制文字

    一.原理分析 浏览器提供了 copy 命令 ,可以复制选中的内容 document.execCommand("copy") 如果是输入框,可以通过 select() 方法,选中输入 ...

  3. js 复制文字、 复制链接到粘贴板

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. WPF中的文字修饰——上划线,中划线,基线与下划线

    原文:WPF中的文字修饰——上划线,中划线,基线与下划线 我们知道,文字的修饰包括:空心字.立体字.划线字.阴影字.加粗.倾斜等.这里只说划线字的修饰方式,按划线的位置,我们可将之分为:上划线.中划线 ...

  5. wpf 深度复制控件,打印控件

    原文:wpf 深度复制控件,打印控件 <Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.micr ...

  6. 点击复制文字到剪贴板兼容性安卓ios

    一般那种活动H5分享可能会用到点击复制文字到剪贴板,很简单的功能 于是搜了一搜:js复制文字到剪贴板,可用结果大致分为两类: 一类是js原生方法,这种方法兼容性不好,不兼容ios: https://d ...

  7. HTML 禁止复制文字

    因为本人平时喜欢看网络小说,但是喜欢看的文通过正经网站或者app都需要收费,让人很是不爽,所以...总之,百度网盘上资源很多.但是问题来了,这些资源肯定不会是作者自己流出的,也不应该是网站或app流出 ...

  8. [WPF] 玩玩彩虹文字及动画

    1. 前言 兴致来了玩玩 WPF 的彩虹文字.不是用 LinearGradientBrush 制作渐变色那种,是指每个文字独立颜色那种彩虹文字.虽然没什么实用价值,但希望这篇文章里用 ItemsCon ...

  9. WPF RichTextBox 自定义文字转超链接

    搬运自StackOverflow private void AddHyperlinkText(string linkURL, string linkName, string TextBeforeLin ...

随机推荐

  1. 01 HDFS 简介

    01.HDFS简介 大纲: hadoop2 介绍 HDFS概述 HDFS读写流程 hadoop2介绍 框架的核心设计是HDFS(存储),mapReduce(分布式计算),YARN(资源管理),为海量的 ...

  2. 决策树-ID3

    id3:无法直接处理数值型数据,可以通过量化方法将数值型数据处理成标称型数据,但涉及太多特征划分,不建议 决策树:的最大优点在于可以给出数据的内在含义,数据形式非常容易理解: 决策树介绍:决策树分类器 ...

  3. Linux下实现秒级的crontab定时任务

    crontab的格式如下 * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 ...

  4. break与continue的区别

    break       在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. continue   的作用是仅仅跳过本次循环,而整个循环体继 ...

  5. 答辩HTML5

    答辩有三个项目,有三个游戏和知乎,游戏都是有js写的,我想说的是想要做一个是那么难啊!老师给了我们游戏的项目还有游戏的思路构成,完成项目.还有一个知乎,也很难,用到HTML,css3,php,数据库, ...

  6. Django Restful Framework (二): ModelSerializer

    时常,你需要对django model 的实例进行序列化.ModelSerializer 类提供了一个捷径让你可以根据 Model 来创建 Serializer. ModelSerializer 类和 ...

  7. Html to Pdf 的另类解决方案

    Background 项目里要求将一个HTML页面(支付结果)生成pdf文档.页面有图片,有表格,貌似开源的iTextSharp应付不了. 在一番搜索之后,找到了wkhtmltopdf,一个命令行的开 ...

  8. Xcode的一个简单的UITests

    国内写Tests的很少,写UITests的更少了...或许只是我眼见不够开阔.网上那么几篇都是Swift的.这里给个简单的OC. - (void)viewDidLoad { [super viewDi ...

  9. apache 虚拟机配置

    <VirtualHost *:80> DocumentRoot /www/htdocs/caipiao ServerName www.aaa.com ServerAlias aaa.com ...

  10. signalR selfhost 版本兼容问题

    一.异常简要说明 最近在学习signalR,i按照http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host 这 ...