优化用户控件和数据处理逻辑
在 `CodeSpanControl.xaml` 中,将布局从 `StackPanel` 更改为 `DockPanel`,并设置 `SelectableTextBlock` 的 `TextWrapping` 属性为 `Wrap`。调整按钮样式,增加 `DockPanel.Dock` 属性。 在 `MarkdownWpfRenderer.cs` 中,提升代码可读性,删除多余行。 修正 `PromptUtil.cs` 中的 XML 标签格式,确保时间和 Excel 文件列信息的正确性。 新增 `XamlToContentConverter` 类,用于将字符串形式的 XAML 转换为 UI 元素。 在 `AiMessageControll.xaml` 中,移除布尔值转换器的注释,增加多个 `TabItem` 以显示不同内容类型,并调整 `TextBox` 属性。 在 `ChatMessage.cs` 中,增加 `ContentXaml` 属性,确保内容更改时触发属性变化通知。 在 `ImportViewModel.cs` 中,调试模式下的 `promptedMsg` 变量替换为 `TEST_AI_CONTENT`,并增加新的测试内容字符串以展示 Markdown 功能。
This commit is contained in:
parent
7506d59b3b
commit
0793330ab2
|
@ -1,32 +1,39 @@
|
|||
<UserControl x:Class="EleCho.MdViewer.Controls.CodeSpanControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:EleCho.MdViewer.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="30" d:DesignWidth="160">
|
||||
<StackPanel Orientation="Horizontal" Margin="5">
|
||||
<local:SelectableTextBlock Text="{Binding Text}" VerticalAlignment="Center"/>
|
||||
<Button x:Name="Copy"
|
||||
Content="复制"
|
||||
Click="Copy_Click"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"
|
||||
Padding="4,0"
|
||||
Opacity="1"
|
||||
Height="20"
|
||||
Background="#AAFFFFFF"
|
||||
BorderThickness="1">
|
||||
<UserControl
|
||||
x:Class="EleCho.MdViewer.Controls.CodeSpanControl"
|
||||
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:local="clr-namespace:EleCho.MdViewer.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
d:DesignHeight="30"
|
||||
d:DesignWidth="160"
|
||||
mc:Ignorable="d">
|
||||
<DockPanel Margin="5">
|
||||
<local:SelectableTextBlock
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Text}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="Copy"
|
||||
Height="20"
|
||||
Padding="4,0"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Background="#AAFFFFFF"
|
||||
BorderThickness="1"
|
||||
Click="Copy_Click"
|
||||
Content="复制"
|
||||
DockPanel.Dock="Right"
|
||||
Opacity="1">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" Value="True">
|
||||
<Setter Property="Opacity" Value="0.8"/>
|
||||
<Setter Property="Opacity" Value="0.8" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -470,7 +470,7 @@ public class MarkdownWpfRenderer
|
|||
}
|
||||
|
||||
|
||||
return codeElement;
|
||||
return codeElement;
|
||||
}
|
||||
|
||||
public FrameworkElement RenderCodeBlock(CodeBlock codeBlock, CancellationToken cancellationToken)
|
||||
|
|
|
@ -15,43 +15,26 @@ class PromptUtil
|
|||
|
||||
当前时间是:
|
||||
|
||||
<current_time>
|
||||
|
||||
{DateTime.Now}
|
||||
|
||||
</current_time>
|
||||
<current_time>{DateTime.Now}</current_time>
|
||||
|
||||
当前用户提问的excel文件列信息为:
|
||||
|
||||
<excel_columns>
|
||||
|
||||
{excelPrompt}
|
||||
|
||||
</excel_columns>
|
||||
<excel_columns>{excelPrompt}</excel_columns>
|
||||
|
||||
用户的问题是:
|
||||
|
||||
<question>
|
||||
|
||||
{msg}
|
||||
|
||||
</question>
|
||||
<question>{msg}</question>
|
||||
|
||||
在回复用户的问题时,你需要遵守以下规则:
|
||||
|
||||
1. 优先保证答案的准确性,其次是简洁明了。
|
||||
|
||||
2. 需要保证你的回答是有逻辑性的,不要让用户感到困惑。
|
||||
|
||||
3. 可以例举1到2个例子来帮助用户更好地理解你的回答中的Excel公式。
|
||||
|
||||
4. 一定要保证文档格式的正确性,避免出现无法显示的内容。
|
||||
|
||||
5. 尽量使用比较简短与易懂的公式来回答用户的问题,避免用户无法理解。
|
||||
6. 当你输出公式时,请使用以下格式进行输出:
|
||||
```Excel_{{列}}
|
||||
=SUM(A1:A100)
|
||||
|
||||
=SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100),SUM(A1:A100)
|
||||
```
|
||||
";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows;
|
||||
using System.Windows.Markup;
|
||||
namespace ExcelHelper.Converter
|
||||
{
|
||||
public class XamlToContentConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is string xamlString && !string.IsNullOrEmpty(xamlString))
|
||||
{
|
||||
try
|
||||
{
|
||||
var xamlObj = XamlReader.Parse(xamlString);
|
||||
//var content = xamlObj as UIElement; // Change XamlReader to System.Windows.Markup.XamlReader
|
||||
return xamlObj;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Handle parsing exceptions if necessary
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
x:Key="BoolToColorConverter"
|
||||
AIMessageColor="#ECECEC"
|
||||
UserMessageColor="#DCF8C6" />
|
||||
|
||||
<!-- 将布尔值转换为对齐方式 (用户消息靠右,AI消息靠左) -->
|
||||
<local1:BoolToAlignmentConverter
|
||||
x:Key="BoolToAlignmentConverter"
|
||||
|
@ -34,7 +33,7 @@
|
|||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<!-- 字符串空判断转换器 -->
|
||||
<local1:StringEmptyToBoolConverter x:Key="StringEmptyToBoolConverter" />
|
||||
|
||||
<local1:XamlToContentConverter x:Key="XamlToContentConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
|
@ -70,12 +69,20 @@
|
|||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Visibility="{Binding Content, Converter={StaticResource StringEmptyToBoolConverter}, ConverterParameter=invert}">
|
||||
|
||||
<TabItem Background="Transparent" Header="文档">
|
||||
<md:MarkdownViewer
|
||||
x:Name="MdViewer"
|
||||
Margin="10"
|
||||
Padding="10"
|
||||
Content="{Binding Content}" />
|
||||
<TabItem.Resources>
|
||||
<Style TargetType="FlowDocumentScrollViewer">
|
||||
<Setter Property="IsToolBarVisible" Value="False" />
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="Zoom" Value="0.6" />
|
||||
</Style>
|
||||
</TabItem.Resources>
|
||||
<FlowDocumentScrollViewer
|
||||
Width="Auto"
|
||||
MinWidth="0"
|
||||
Document="{Binding FlowDocument}"
|
||||
VerticalScrollBarVisibility="Visible" />
|
||||
</TabItem>
|
||||
<TabItem Background="Transparent" Header="文本">
|
||||
<TextBox
|
||||
|
@ -84,18 +91,51 @@
|
|||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="0"
|
||||
Text="{Binding Content}" />
|
||||
Text="{Binding Content}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalScrollBarVisibility="Auto" />
|
||||
</TabItem>
|
||||
<TabItem Background="Transparent" Header="XAML">
|
||||
<TextBox
|
||||
Margin="5"
|
||||
Padding="5"
|
||||
Background="Transparent"
|
||||
BorderBrush="Transparent"
|
||||
BorderThickness="0"
|
||||
Text="{Binding ContentXaml}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalScrollBarVisibility="Auto" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<DockPanel>
|
||||
<hc:ButtonGroup Margin="5,0">
|
||||
<hc:ButtonGroup Margin="5">
|
||||
<Button
|
||||
Height="20"
|
||||
hc:IconElement.Geometry="{StaticResource WindowRestoreGeometry}"
|
||||
Background="Transparent"
|
||||
FontSize="10"
|
||||
Foreground="#99000000" />
|
||||
Foreground="#99000000"
|
||||
ToolTip="复制所有内容" />
|
||||
<Button
|
||||
Height="20"
|
||||
hc:IconElement.Geometry="{StaticResource RotateRightGeometry}"
|
||||
hc:IconElement.Height="12"
|
||||
Background="Transparent"
|
||||
FontSize="10"
|
||||
FontWeight="Bold"
|
||||
Foreground="#99000000"
|
||||
ToolTip="重新生成" />
|
||||
|
||||
<Button
|
||||
Height="20"
|
||||
hc:IconElement.Geometry="{StaticResource SaveGeometry}"
|
||||
hc:IconElement.Height="12"
|
||||
Background="Transparent"
|
||||
FontSize="10"
|
||||
FontWeight="Bold"
|
||||
Foreground="#99000000"
|
||||
ToolTip="保存到文件" />
|
||||
</hc:ButtonGroup>
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<TextBlock
|
||||
|
@ -150,8 +190,8 @@
|
|||
<DockPanel>
|
||||
<hc:ComboBox Height="30" SelectedIndex="1">
|
||||
<ComboBoxItem Content="DeepSeek-V3" />
|
||||
<ComboBoxItem Content="DeepSeek-V3" />
|
||||
<ComboBoxItem Content="DeepSeek-V3" />
|
||||
<ComboBoxItem Content="DeepSeek-R1" />
|
||||
<ComboBoxItem Content="豆包-1.5-Pro" />
|
||||
</hc:ComboBox>
|
||||
<Button
|
||||
Height="30"
|
||||
|
|
|
@ -68,7 +68,7 @@ public partial class AiMessageControll : UserControl
|
|||
public AiMessageControll()
|
||||
{
|
||||
InitializeComponent();
|
||||
//DataContext = this;
|
||||
//DataContext = this;
|
||||
WeakReferenceMessenger.Default.Register<ScrollToEndMessage>("MessageListScrollToEnd", (o, s) => {
|
||||
|
||||
Dispatcher.BeginInvoke(() =>
|
||||
|
|
|
@ -21,7 +21,8 @@ public class ChatMessage : INotifyPropertyChanged
|
|||
{
|
||||
_content = value;
|
||||
OnPropertyChanged(nameof(Content));
|
||||
//OnPropertyChanged(nameof(FlowDocument));
|
||||
OnPropertyChanged(nameof(FlowDocument));
|
||||
OnPropertyChanged(nameof(ContentXaml));
|
||||
}
|
||||
}
|
||||
public FlowDocument FlowDocument
|
||||
|
@ -31,6 +32,7 @@ public class ChatMessage : INotifyPropertyChanged
|
|||
var doc = MarkdownXaml.ToFlowDocument(Content,
|
||||
new MarkdownPipelineBuilder()
|
||||
.UseXamlSupportedExtensions()
|
||||
.UseAdvancedExtensions()
|
||||
.Build()
|
||||
);
|
||||
return doc;
|
||||
|
@ -38,6 +40,18 @@ public class ChatMessage : INotifyPropertyChanged
|
|||
|
||||
set => OnPropertyChanged(nameof(FlowDocument));
|
||||
}
|
||||
|
||||
public string ContentXaml
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
var xaml = MarkdownXaml.ToXaml(Content, new MarkdownPipelineBuilder().UseXamlSupportedExtensions().UseAdvancedExtensions().Build());
|
||||
return xaml;
|
||||
}
|
||||
|
||||
set => OnPropertyChanged(nameof(ContentXaml));
|
||||
}
|
||||
private bool _isUser;
|
||||
public bool IsUser
|
||||
{
|
||||
|
|
|
@ -323,7 +323,7 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
|
|||
Messages.Add(aiChat);
|
||||
var promptedMsg = PromptUtil.UsePrompt(message,ExcelPromptString);
|
||||
#if DEBUG
|
||||
var results = promptedMsg.Split('\n');
|
||||
var results = TEST_AI_CONTENT.Split('\n');
|
||||
foreach(var result in results)
|
||||
{
|
||||
aiChat.Content += result;
|
||||
|
@ -348,15 +348,191 @@ public partial class ImportViewModel : ObservableRecipient, IViewModel
|
|||
|
||||
|
||||
private static string TEST_AI_CONTENT = @"
|
||||
```Excel_H
|
||||
1231231122222222222222222222
|
||||
123
|
||||
1
|
||||
23
|
||||
12
|
||||
3
|
||||
12
|
||||
# Welcome to Leanote! 欢迎来到Leanote!
|
||||
|
||||
## 1. 排版
|
||||
|
||||
**粗体** *斜体*
|
||||
|
||||
~~这是一段错误的文本。~~
|
||||
|
||||
引用:
|
||||
|
||||
> 引用Leanote官方的话, 为什么要做Leanote, 原因是...
|
||||
|
||||
有充列表:
|
||||
1. 支持Vim
|
||||
2. 支持Emacs
|
||||
|
||||
无序列表:
|
||||
|
||||
- 项目1
|
||||
- 项目2
|
||||
|
||||
|
||||
## 2. 图片与链接
|
||||
|
||||
图片:
|
||||

|
||||
链接:
|
||||
|
||||
[这是去往Leanote官方博客的链接](http://leanote.leanote.com)
|
||||
|
||||
## 3. 标题
|
||||
|
||||
以下是各级标题, 最多支持5级标题
|
||||
|
||||
```
|
||||
# h1
|
||||
## h2
|
||||
### h3
|
||||
#### h4
|
||||
##### h4
|
||||
###### h5
|
||||
```
|
||||
|
||||
## 4. 代码
|
||||
|
||||
示例:
|
||||
|
||||
function get(key) {
|
||||
return m[key];
|
||||
}
|
||||
|
||||
代码高亮示例:
|
||||
|
||||
``` javascript
|
||||
/**
|
||||
* nth element in the fibonacci series.
|
||||
* @param n >= 0
|
||||
* @return the nth element, >= 0.
|
||||
*/
|
||||
function fib(n) {
|
||||
var a = 1, b = 1;
|
||||
var tmp;
|
||||
while (--n >= 0) {
|
||||
tmp = a;
|
||||
a += b;
|
||||
b = tmp;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
document.write(fib(10));
|
||||
```
|
||||
|
||||
```python
|
||||
class Employee:
|
||||
empCount = 0
|
||||
|
||||
def __init__(self, name, salary):
|
||||
self.name = name
|
||||
self.salary = salary
|
||||
Employee.empCount += 1
|
||||
```
|
||||
|
||||
# 5. Markdown 扩展
|
||||
|
||||
Markdown 扩展支持:
|
||||
|
||||
* 表格
|
||||
* 定义型列表
|
||||
* Html 标签
|
||||
* 脚注
|
||||
* 目录
|
||||
* 时序图与流程图
|
||||
* MathJax 公式
|
||||
|
||||
## 5.1 表格
|
||||
|
||||
Item | Value
|
||||
-------- | ---
|
||||
Computer | \$1600
|
||||
Phone | \$12
|
||||
Pipe | \$1
|
||||
|
||||
可以指定对齐方式, 如Item列左对齐, Value列右对齐, Qty列居中对齐
|
||||
|
||||
| Item | Value | Qty |
|
||||
| :------- | ----: | :---: |
|
||||
| Computer | \$1600 | 5 |
|
||||
| Phone | \$12 | 12 |
|
||||
| Pipe | \$1 | 234 |
|
||||
|
||||
|
||||
## 5.2 定义型列表
|
||||
|
||||
名词 1
|
||||
: 定义 1(左侧有一个可见的冒号和四个不可见的空格)
|
||||
|
||||
代码块 2
|
||||
: 这是代码块的定义(左侧有一个可见的冒号和四个不可见的空格)
|
||||
|
||||
代码块(左侧有八个不可见的空格)
|
||||
|
||||
|
||||
## 5.4 脚注
|
||||
|
||||
Leanote[^footnote]来创建一个脚注
|
||||
[^footnote]: Leanote是一款强大的开源云笔记产品.
|
||||
|
||||
## 5.5 目录
|
||||
|
||||
通过 `[TOC]` 在文档中插入目录, 如:
|
||||
|
||||
[TOC]
|
||||
|
||||
## 5.6 时序图与流程图
|
||||
|
||||
```sequence
|
||||
Alice->Bob: Hello Bob, how are you?
|
||||
Note right of Bob: Bob thinks
|
||||
Bob-->Alice: I am good thanks!
|
||||
```
|
||||
|
||||
流程图:
|
||||
|
||||
```flow
|
||||
st=>start: Start
|
||||
e=>end
|
||||
op=>operation: My Operation
|
||||
cond=>condition: Yes or No?
|
||||
|
||||
st->op->cond
|
||||
cond(yes)->e
|
||||
cond(no)->op
|
||||
```
|
||||
|
||||
> **提示:** 更多关于时序图与流程图的语法请参考:
|
||||
|
||||
> - [时序图语法](http://bramp.github.io/js-sequence-diagrams/)
|
||||
> - [流程图语法](http://adrai.github.io/flowchart.js)
|
||||
|
||||
## 5.7 MathJax 公式
|
||||
|
||||
$ 表示行内公式:
|
||||
|
||||
质能守恒方程可以用一个很简洁的方程式 $E=mc^2$ 来表达。
|
||||
|
||||
$$ 表示整行公式:
|
||||
|
||||
$$\sum_{i=1}^n a_i=0$$
|
||||
|
||||
$$f(x_1,x_x,\ldots,x_n) = x_1^2 + x_2^2 + \cdots + x_n^2 $$
|
||||
|
||||
$$\sum^{j-1}_{k=0}{\widehat{\gamma}_{kj} z_k}$$
|
||||
|
||||
更复杂的公式:
|
||||
$$
|
||||
\begin{eqnarray}
|
||||
\vec\nabla \times (\vec\nabla f) & = & 0 \cdots\cdots梯度场必是无旋场\\
|
||||
\vec\nabla \cdot(\vec\nabla \times \vec F) & = & 0\cdots\cdots旋度场必是无散场\\
|
||||
\vec\nabla \cdot (\vec\nabla f) & = & {\vec\nabla}^2f\\
|
||||
\vec\nabla \times(\vec\nabla \times \vec F) & = & \vec\nabla(\vec\nabla \cdot \vec F) - {\vec\nabla}^2 \vec F\\
|
||||
\end{eqnarray}
|
||||
$$
|
||||
|
||||
访问 [MathJax](http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference) 参考更多使用方法。
|
||||
";
|
||||
#region Props
|
||||
[ObservableProperty]
|
||||
|
|
Loading…
Reference in New Issue