项目里需要实现一个表达式编辑的功能 其中可以嵌入自定义表达式参数为各种信号
如:up.Signal(10) + down.Signal(10,20,30) > 0
于是废了半天时间写了个表达式编辑器 使用的是RichTextBox 没有找到其他比较好的富文本编辑框
up.Signal(10) 和down.Signal(10,20,30) 在载入、添加表达式时翻译成黑框并根据表达式内容显示描述
效果
测试代码
XAML
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.ContextMenu>
<ContextMenu>
<MenuItem Header="dddd"/>
<MenuItem Header="dddd"/>
<MenuItem Header="dddd"/>
<MenuItem Header="dddd"/>
</ContextMenu>
</Window.ContextMenu>
<Grid>
<RichTextBox Name="RichTextBoxOutput"
VerticalContentAlignment="Center" HorizontalAlignment="Left"
Foreground="#FF4EC9B0"
IsDocumentEnabled="True"
Height="276" Margin="10,39,0,0" VerticalAlignment="Top" Width="567" FontSize="14" FontWeight="Bold">
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0,1,0,1"/>
</Style>
<Style TargetType="{x:Type Run}">
<Setter Property="BaselineAlignment" Value="Center"/>
</Style>
</RichTextBox.Resources>
<FlowDocument>
<Paragraph>
<Run Text="RichTextBox"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<Button Content="添加表达式" HorizontalAlignment="Left" Margin="628,75,0,0" VerticalAlignment="Top" Width="117" Height="206" Click="Button_Click"/>
<Button Content="解析表达式" HorizontalAlignment="Left" Margin="628,296,0,0" VerticalAlignment="Top" Width="117" Height="114" Click="Button_Click_1"/>
</Grid>
</Window>
后台
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
namespace WpfApp2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
RichTextBoxOutput.Document = new FlowDocument(new Paragraph());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Border border = new Border();
border.Child = new TextBlock()
{
FontSize = 12,
FontStyle = FontStyles.Normal,
FontWeight = FontWeights.Normal,
Text = "表达式所指定的表达的的",
Margin = new Thickness(2, 0, 2, 0),
Foreground = new SolidColorBrush(Colors.White),
};
border.CornerRadius = new CornerRadius(3, 3, 3, 3);
border.BorderThickness = new Thickness(2, 2, 2, 2);
border.Background = new SolidColorBrush(Color.FromArgb(255, 30, 30, 30));
border.Opacity = 0.7;
border.Effect = new DropShadowEffect() { BlurRadius = 5, ShadowDepth = 2, Direction = -90 };
InlineUIContainer container = new InlineUIContainer(border);
container.MouseLeftButtonDown += Container_MouseLeftButtonDown1;
container.ContextMenu = this.ContextMenu;
var Paragraph = RichTextBoxOutput.Document.Blocks.LastBlock as Paragraph;
Paragraph.Inlines.Add(container);
}
private void Container_MouseLeftButtonDown1(object sender, MouseButtonEventArgs e)
{
var send = sender as InlineUIContainer;
var b = send.Child as Border;
var text = b.Child as TextBlock;
text.Text = "123456";
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var doc = this.RichTextBoxOutput.Document;
foreach (Paragraph item in doc.Blocks)
{
foreach (var iline in item.Inlines)
{
var lpRun = iline as Run;
var lpInLine = iline as InlineUIContainer;
if (lpInLine != null)
{
Console.WriteLine(lpInLine.Child);
}else if (lpRun != null)
{
Console.WriteLine(lpRun.Text);
}
else
{
throw new Exception("");
}
}
}
}
}
}
鉴于 wpf 里 RichTextBox的Document 是没法在Xaml里面绑定的
于是 继承RichTextBox 重写一下 Document属性
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
public class RichTextBoxEx : RichTextBox
{
public new FlowDocument Document
{
get { return (FlowDocument)GetValue(DocumentProperty); }
set { SetValue(DocumentProperty, value); }
}
public static readonly DependencyProperty DocumentProperty = DependencyProperty.Register("Document", typeof(FlowDocument), typeof(RichTextBoxEx), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnDucumentChanged)));
private static void OnDucumentChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
((RichTextBox)target).Document = (FlowDocument)e.NewValue;
}
}