wpf-利用装饰器制作 彩色字体+可选中+可复制 的textblock
程序员文章站
2022-06-07 15:16:11
...
效果如下图所示:
实现要点:
- 彩色字体可以用TextBlock的Run实现
- “可选中”可以通过装饰器实现
- 注意鼠标事件处理
前台
<ScrollViewer Width="400" x:Name="colorScrollViewer" HorizontalScrollBarVisibility="Visible" >
<TextBlock x:Name="colorSeq" ScrollViewer.CanContentScroll="True"
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.ScrollUnit="Pixel"
VirtualizingPanel.VirtualizationMode="Recycling"
MouseLeftButtonDown="colorSeq_MouseLeftButtonDown"
PreviewMouseLeftButtonDown="colorSeq_PreviewMouseLeftButtonDown"
PreviewMouseLeftButtonUp="colorSeq_PreviewMouseLeftButtonUp"
/>
</ScrollViewer>
后台
public partial class WPInfoWindow : Window
{
private Point _startMousePosition { set; get; }
private TextPointer _startPt { set; get; }
private TextBlockSelectedAdorner _tbsAdorner { set; get; }
public WPInfoWindow()
{
InitializeComponent();
string t = "";
string[] dict = new string[] {"A","C","G","T" };
// 搞点随机字符串
Random rd = new Random();
for (int i = 0; i < 4000; i++) {
string c = dict[rd.Next(0, 4)];
Run r = new Run();
r.Text = c;
// 给点不同的颜色
switch (c) {
case "A":
r.Foreground = Brushes.Green;
break;
case "C":
r.Foreground = Brushes.Blue;
break;
case "G":
r.Foreground = Brushes.Black;
break;
case "T":
r.Foreground = Brushes.Red;
break;
}
this.colorSeq.Inlines.Add(r);
}
}
...
private void colorSeq_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Point lastMousePosition = e.GetPosition(this.colorSeq);
TextPointer tp = this.colorSeq.GetPositionFromPoint(lastMousePosition, true);
TextRange tr = new TextRange(_startPt, tp);
string selectedText = tr.Text;
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.colorSeq);
Rect rect = new Rect(_startMousePosition.X, 0.0, lastMousePosition.X-_startMousePosition.X, 30);
this._tbsAdorner = new TextBlockSelectedAdorner(this.colorSeq, rect);
adornerLayer.Add(this._tbsAdorner);
// 省去复制到剪贴板那步,自己想咋处理咋处理
MessageBox.Show(selectedText);
}
private void colorSeq_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
_startMousePosition = e.GetPosition(this.colorSeq);
_startPt = this.colorSeq.GetPositionFromPoint(_startMousePosition, true);
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.colorSeq);
if (this._tbsAdorner != null)
{
adornerLayer.Remove(this._tbsAdorner);
}
}
private void colorSeq_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.colorSeq);
_cursorAdorner = new TextBlockSelectedAdorner(this.colorSeq, new Rect(_startMousePosition.X, 0.0, 0, 30));
adornerLayer.Add(_cursorAdorner);
}
...
public class TextBlockSelectedAdorner : Adorner {
// 被装饰的元素
Rect _maskRect;
// 基类初始化
public TextBlockSelectedAdorner(UIElement element, Rect rect) : base(element) {
this._maskRect = rect;
}
// 实现装饰器呈现的行为
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
Pen renderPen = new Pen(new SolidColorBrush(Colors.Red), 0);
SolidColorBrush brush = new SolidColorBrush(Color.FromArgb(30,0,0,255));
drawingContext.DrawRectangle(brush, renderPen, this._maskRect);
}
}
上一篇: WPF窗口等比例缩放,自适应分辨率
下一篇: linux常用命令