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 > )
{
//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的更多相关文章
- WPF模拟探照灯文字
原文:WPF模拟探照灯文字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1835936 ...
- js复制文字
一.原理分析 浏览器提供了 copy 命令 ,可以复制选中的内容 document.execCommand("copy") 如果是输入框,可以通过 select() 方法,选中输入 ...
- js 复制文字、 复制链接到粘贴板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- WPF中的文字修饰——上划线,中划线,基线与下划线
原文:WPF中的文字修饰——上划线,中划线,基线与下划线 我们知道,文字的修饰包括:空心字.立体字.划线字.阴影字.加粗.倾斜等.这里只说划线字的修饰方式,按划线的位置,我们可将之分为:上划线.中划线 ...
- wpf 深度复制控件,打印控件
原文:wpf 深度复制控件,打印控件 <Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.micr ...
- 点击复制文字到剪贴板兼容性安卓ios
一般那种活动H5分享可能会用到点击复制文字到剪贴板,很简单的功能 于是搜了一搜:js复制文字到剪贴板,可用结果大致分为两类: 一类是js原生方法,这种方法兼容性不好,不兼容ios: https://d ...
- HTML 禁止复制文字
因为本人平时喜欢看网络小说,但是喜欢看的文通过正经网站或者app都需要收费,让人很是不爽,所以...总之,百度网盘上资源很多.但是问题来了,这些资源肯定不会是作者自己流出的,也不应该是网站或app流出 ...
- [WPF] 玩玩彩虹文字及动画
1. 前言 兴致来了玩玩 WPF 的彩虹文字.不是用 LinearGradientBrush 制作渐变色那种,是指每个文字独立颜色那种彩虹文字.虽然没什么实用价值,但希望这篇文章里用 ItemsCon ...
- WPF RichTextBox 自定义文字转超链接
搬运自StackOverflow private void AddHyperlinkText(string linkURL, string linkName, string TextBeforeLin ...
随机推荐
- [转]socket 通俗解释
socket是网络编程的基础,本文用打电话来类比socket通信中建立TCP连接的过程. socket函数,表示你买了或者借了一部手机. bind函数,告诉别人你的手机号码,让他们给你打电 ...
- windows安装zookeeper-单机模式
zookeeper下载地址:http://zookeeper.apache.org/releases.html#download 本次使用的是3.4.9版本 前提:请安装JDK 安装: 创建安装目 ...
- C#如何获取本机网络IP地址
在开发过程中我们经常会碰到需要IP地址,用来记录用户上次登录的时间地址,或者sokect网络编程等等,下面介绍两种方式: 1. public static string GetIP() { retur ...
- C和指针 第十六章 标准函数库
字符串转换: long int strtol(char const *string, char **unused, int base); 将字符串转换为数值形式,遇到非法字符停止,如果stop不是NU ...
- mac php环境启动
mac 环境下,用brew安装php相关环境启动命令 说明 这里php,mysql,nginx都是用brew安装,安装目录默认,在Cellar下面 php-fpm 带配置重启 /*注意权限,加 sud ...
- Git 如何只更新项目中某个目录里的文件
Git由于在远端和本地都有一个代码库, 这样更新单个文件比SVN要麻烦一点. 1. 如果想拿远端git服务器上的最新版本(或某个特定版本)覆盖本地的修改,可以使用git pull命令, 但这会 ...
- javadoc生成出现错误“编码 GBK 的不可映射字符”
https://my.oschina.net/tiancai/blog/155299 http://heweina2007.iteye.com/blog/1561387 http://blog.csd ...
- JavaScript 日期选择器 Pikaday
找一些插件的过程实在太痛苦了...好容易找到一个,赶紧记录下.免得以后重复浪费时间在这上面. 插件名:Pikaday github地址:https://github.com/dbushell/Pika ...
- RBAC权限模型
RBAC 现在大多数的管理系统都是基于RBAC开发的组织机构权限框架.所有的操作都是基于角色(Role)来完成的.我们先从需求的角度出发,来了解关于系统权限管理. 用户A和用户B都属于研发部,我们可以 ...
- echarts饼图
1.添加点击事件并跳转到不同的页面 // 路径配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist/' ...