using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Threading;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Core.Geoprocessing;
using LinkToolAddin.client;
using LinkToolAddin.common;
using LinkToolAddin.host;
using LinkToolAddin.host.llm;
using LinkToolAddin.host.llm.entity;
using LinkToolAddin.message;
using LinkToolAddin.resource;
using LinkToolAddin.server;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Layout;
using ModelContextProtocol.Client;
using ModelContextProtocol.Protocol.Types;
using ModelContextProtocol.Server;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace LinkToolAddin.ui.dockpane
{
public class ItemModel
{
public string Content { get; set; }
}
///
/// Interaction logic for DialogDockpaneView.xaml
///
public partial class DialogDockpaneView : UserControl
{
private static ILog log = LogManager.GetLogger(typeof(DialogDockpaneView));
private List idList = new List();
private ConcurrentDictionary messageDict = new ConcurrentDictionary();
private ConcurrentDictionary borderItemsDict = new ConcurrentDictionary();
public DialogDockpaneView()
{
InitLogger();
InitializeComponent();
DataContext = this;
}
private async void TestServer_OnClick(object sender, RoutedEventArgs e)
{
log.Info("TestServer Clicked");
}
protected void InitLogger()
{
// 1. 创建控制台输出器(Appender)
var consoleAppender = new ConsoleAppender
{
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
};
consoleAppender.ActivateOptions(); // 激活配置
// 2. 创建文件滚动输出器(按大小滚动)
var fileAppender = new RollingFileAppender
{
File = Path.Combine("Logs", "D:\\linktool_app.log"), // 日志文件路径
AppendToFile = true, // 追加模式
RollingStyle = RollingFileAppender.RollingMode.Size, // 按文件大小滚动
MaxSizeRollBackups = 10, // 保留 10 个历史文件
MaximumFileSize = "1MB", // 单个文件最大 1MB
StaticLogFileName = true, // 固定文件名(否则自动追加序号)
Layout = new PatternLayout("%date [%thread] %-5level %logger - %message%newline"),
Threshold = log4net.Core.Level.Info // 仅输出 Info 及以上级别
};
fileAppender.ActivateOptions(); // 激活配置
// 3. 直接通过 BasicConfigurator 注册 Appender
BasicConfigurator.Configure(consoleAppender, fileAppender);
log = LogManager.GetLogger(typeof(DialogDockpaneView));
// 测试日志输出
log.Debug("Debug 日志(控制台可见)");
log.Info("Info 日志(控制台和文件可见)");
log.Error("Error 日志(严重问题)");
}
private void SendButton_OnClick(object sender, RoutedEventArgs e)
{
StatusTextBlock.Text = "正在读取用户输入和工具列表";
string question = QuestionTextbox.Text;
string defaultGdbPath = Project.Current.DefaultGeodatabasePath;
string gdbPath = @"";
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
MessageListItem userMsg = new ChatMessageItem()
{
content = question,
role = "user",
type = MessageType.CHAT_MESSAGE,
id = timestamp.ToString()
};
Border userMsgBoder = GetUserChatBorder(userMsg);
idList.Add(timestamp.ToString());
messageDict[timestamp.ToString()] = userMsg;
QuestionTextbox.Text = "";
borderItemsDict[timestamp.ToString()] = userMsgBoder;
ChatHistoryStackPanel.Children.Add(userMsgBoder);
string model = (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString() is null ? "qwen3-235b-a22b" : (ModelComboBox.SelectedItem as ComboBoxItem).Content.ToString();
if (model == "自定义")
{
model = ShowInputBox("自定义模型", "请输入模型名称:", "");
}
ScrollViewer.ScrollToBottom();
Gateway.SendMessageStream(question,model,defaultGdbPath,NewMessage_Recall);
}
private string ShowInputBox(string title, string message, string defaultValue = "")
{
// 创建一个自定义的输入对话框
var dialog = new System.Windows.Window
{
Title = title,
Width = 300,
Height = 150,
WindowStyle = WindowStyle.ToolWindow,
ResizeMode = ResizeMode.NoResize,
Topmost = true,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
// 设置对话框内容
var stackPanel = new StackPanel { Margin = new Thickness(10) };
stackPanel.Children.Add(new TextBlock { Text = message, Margin = new Thickness(0, 0, 0, 5) });
var textBox = new TextBox { Text = defaultValue, Margin = new Thickness(0, 0, 0, 10) };
stackPanel.Children.Add(textBox);
var buttonPanel = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right };
var okButton = new Button { Content = "确定", Width = 75, Margin = new Thickness(0, 0, 5, 0) };
okButton.Click += (sender, e) => dialog.Close();
var cancelButton = new Button { Content = "取消", Width = 75 };
cancelButton.Click += (sender, e) => { textBox.Text = null; dialog.Close(); };
buttonPanel.Children.Add(okButton);
buttonPanel.Children.Add(cancelButton);
stackPanel.Children.Add(buttonPanel);
dialog.Content = stackPanel;
// 显示对话框并获取结果
dialog.ShowDialog();
return textBox.Text;
}
public void NewMessage_Recall(MessageListItem msg)
{
string msgId = msg.id;
log.Info(msg.content);
double verticalOffset = ScrollViewer.VerticalOffset;
double viewportHeight = ScrollViewer.ViewportHeight;
double contentHeight = ChatHistoryStackPanel.ActualHeight;
double tolerance = 24;
if (!idList.Contains(msgId))
{
//不存在该消息,需添加到ListView中
if (msg.content == "")
{
if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
}
return;
}
idList.Add(msgId);
messageDict[msgId] = msg;
if (msg.role == "user")
{
if (msg.type == MessageType.TOOL_MESSAGE)
{
Border border = GetToolChatBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "正在执行工具";
}else if (msg.type == MessageType.CHAT_MESSAGE)
{
Border border = GetUserChatBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "正在读取用户输入";
}
}
else if(msg.role == "assistant")
{
if (msg.type == MessageType.REASON_MESSAGE)
{
Border border = GetAiReasonBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "深度思考中";
}else if (msg.type == MessageType.CHAT_MESSAGE)
{
Border border = GetAiChatBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "回答生成中";
}
}
else if (msg.role == "system")
{
if (msg.type == MessageType.WARNING)
{
Border border = GetWarningChatBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "出现警告信息";
}else if (msg.type == MessageType.ERROR)
{
Border border = GetWarningChatBorder(msg);
borderItemsDict[msgId] = border;
ChatHistoryStackPanel.Children.Add(border);
StatusTextBlock.Text = "出现错误信息";
}
}
}
else
{
//已有该消息,只需要修改内容
messageDict[msgId] = msg;
if (msg.content == "")
{
if (msg.type == MessageType.END_TAG)
{
StatusTextBlock.Text = "";
}
ChatHistoryStackPanel.Children.Remove(borderItemsDict[msgId]);
borderItemsDict.TryRemove(msgId, out Border border);
messageDict.TryRemove(msgId, out MessageListItem tempMsg);
idList.Remove(msgId);
}
if (msg.role == "user")
{
if (msg.type == MessageType.TOOL_MESSAGE)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBlock textBlock = grid.Children[1] as TextBlock;
ToolMessageItem msgItem = msg as ToolMessageItem;
textBlock.Text = msgItem.toolName + " | " + msgItem.status;
Button resButton = grid.Children[3] as Button;
resButton.Tag = msg;
StatusTextBlock.Text = "正在执行工具";
}else if (msg.type == MessageType.CHAT_MESSAGE)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBox textBox = grid.Children[1] as TextBox;
textBox.Text = msg.content;
StatusTextBlock.Text = "正在读取用户输入";
}
}
else if(msg.role == "assistant")
{
if (msg.type == MessageType.REASON_MESSAGE)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBox textBox = grid.Children[0] as TextBox;
textBox.Text = msg.content;
StatusTextBlock.Text = "深度思考中";
}else if (msg.type == MessageType.CHAT_MESSAGE)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBox textBox = grid.Children[1] as TextBox;
textBox.Text = msg.content;
StatusTextBlock.Text = "回答生成中";
}
}else if (msg.role == "system")
{
if (msg.type == MessageType.WARNING)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBox textBox = grid.Children[1] as TextBox;
textBox.Text = msg.content;
StatusTextBlock.Text = "出现警告信息";
}else if (msg.type == MessageType.ERROR)
{
Border borderItem = borderItemsDict[msgId];
Grid grid = borderItem.Child as Grid;
TextBox textBox = grid.Children[1] as TextBox;
textBox.Text = msg.content;
}
}
}
if (Math.Abs(verticalOffset + viewportHeight - contentHeight) < tolerance)
{
ScrollViewer.ScrollToBottom();
}
}
private Border GetAiChatBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(8, 12, 8, 12);
border.BorderThickness = new Thickness(0);
// border.Background = Brushes.DarkSeaGreen;
Grid grid = new Grid();
Image icon = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.linktool.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
TextBox textBox = new TextBox();
grid.Children.Add(icon);
grid.Children.Add(textBox);
Grid.SetColumn(icon, 0);
Grid.SetColumn(textBox, 1);
textBox.IsReadOnly = true;
textBox.BorderThickness = new Thickness(0);
textBox.Background = Brushes.Transparent;
textBox.Text = msg.content;
textBox.TextWrapping = TextWrapping.Wrap;
border.Child = grid;
return border;
}
private Border GetAiReasonBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(8, 12, 8, 12);
border.BorderThickness = new Thickness(0);
// border.Background = Brushes.DarkSeaGreen;
Grid grid = new Grid();
Image icon = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.linktool.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
Image fold = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.fold.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
Image unfold = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.unfold.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(16, GridUnitType.Pixel)});
TextBox textBox = new TextBox();
// grid.Children.Add(icon);
grid.Children.Add(textBox);
// Grid.SetColumn(icon, 0);
Grid.SetColumn(textBox, 1);
textBox.IsReadOnly = true;
textBox.Foreground = Brushes.Gray;
textBox.BorderThickness = new Thickness(2,0,0,0);
textBox.BorderBrush = Brushes.Gray;
textBox.Background = Brushes.Transparent;
textBox.Text = msg.content;
textBox.TextWrapping = TextWrapping.Wrap;
Button button = new Button();
StackPanel panel = new StackPanel();
panel.Orientation = Orientation.Horizontal;
panel.Children.Add(fold);
button.Content = panel;
button.BorderThickness = new Thickness(0);
button.Background = Brushes.Transparent;
button.Width = 16;
button.Height = 16;
button.Padding = new Thickness(0);
button.HorizontalAlignment = HorizontalAlignment.Center;
button.VerticalAlignment = VerticalAlignment.Top;
button.Tag = "fold";
button.Click += FoldButton_OnClick;
Grid.SetColumn(button, 2);
grid.Children.Add(button);
border.Child = grid;
return border;
}
private void FoldButton_OnClick(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
string tag = button.Tag.ToString();
if (tag == "fold")
{
button.Tag = "unfold";
Grid grid = button.Parent as Grid;
TextBox textBox = grid.Children[0] as TextBox;
textBox.Visibility = Visibility.Collapsed;
StackPanel stackPanel = button.Content as StackPanel;
Image unfold = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.unfold.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
stackPanel.Children.Clear();
stackPanel.Children.Add(unfold);
}
else
{
button.Tag = "fold";
Image fold = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.fold.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
Grid grid = button.Parent as Grid;
TextBox textBox = grid.Children[0] as TextBox;
textBox.Visibility = Visibility.Visible;
StackPanel stackPanel = button.Content as StackPanel;
stackPanel.Children.Clear();
stackPanel.Children.Add(fold);
}
}
private Border GetUserChatBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(8, 12, 8, 12);
border.BorderThickness = new Thickness(0);
// border.Background = Brushes.DarkSeaGreen;
Grid grid = new Grid();
Image icon = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.user.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Top
};
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
TextBox textBox = new TextBox();
textBox.HorizontalAlignment = HorizontalAlignment.Right;
grid.Children.Add(icon);
grid.Children.Add(textBox);
Grid.SetColumn(icon, 1);
Grid.SetColumn(textBox, 0);
textBox.Background = Brushes.Transparent;
textBox.IsReadOnly = true;
textBox.BorderThickness = new Thickness(0);
textBox.Text = msg.content;
textBox.TextWrapping = TextWrapping.Wrap;
border.Child = grid;
return border;
}
private Border GetWarningChatBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(24);
border.Padding = new Thickness(8);
border.BorderThickness = new Thickness(1);
border.BorderBrush = Brushes.DarkGoldenrod;
border.CornerRadius = new CornerRadius(3);
border.Background = Brushes.Moccasin;
Grid grid = new Grid();
// Image icon = new Image()
// {
// Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"),
// Stretch = Stretch.Fill,
// HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
// };
// icon.Margin = new Thickness(0, 0, 8, 0);
// grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
TextBlock textBlock = new TextBlock();
textBlock.Text = (msg as ChatMessageItem).content;
textBlock.TextWrapping = TextWrapping.Wrap;
// grid.Children.Add(icon);
grid.Children.Add(textBlock);
// Grid.SetColumn(icon, 0);
Grid.SetColumn(textBlock, 1);
border.Child = grid;
return border;
}
private Border GetErrorChatBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(24);
border.Padding = new Thickness(8);
border.BorderThickness = new Thickness(1);
border.BorderBrush = Brushes.Crimson;
border.CornerRadius = new CornerRadius(3);
border.Background = Brushes.LightPink;
Grid grid = new Grid();
// Image icon = new Image()
// {
// Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"),
// Stretch = Stretch.Fill,
// HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
// };
// icon.Margin = new Thickness(0, 0, 8, 0);
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
TextBlock textBlock = new TextBlock();
textBlock.Text = (msg as ChatMessageItem).content;
textBlock.TextWrapping = TextWrapping.Wrap;
// grid.Children.Add(icon);
grid.Children.Add(textBlock);
// Grid.SetColumn(icon, 0);
Grid.SetColumn(textBlock, 1);
border.Child = grid;
return border;
}
private Border GetToolChatBorder(MessageListItem msg)
{
Border border = new Border();
border.Margin = new Thickness(24);
border.Padding = new Thickness(8);
border.BorderThickness = new Thickness(1);
border.BorderBrush = Brushes.Gray;
border.CornerRadius = new CornerRadius(3);
// border.Background = Brushes.DarkSeaGreen;
Grid grid = new Grid();
Image icon = new Image()
{
Source = LocalResource.ReadImageByResource("LinkToolAddin.resource.img.tool.png"),
Stretch = Stretch.Fill,
HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center
};
icon.Margin = new Thickness(0, 0, 8, 0);
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(24, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)});
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)});
TextBlock textBlock = new TextBlock();
ToolMessageItem toolMsg = msg as ToolMessageItem;
textBlock.Text = toolMsg.toolName + " | " + toolMsg.status;
textBlock.TextWrapping = TextWrapping.Wrap;
grid.Children.Add(icon);
grid.Children.Add(textBlock);
Grid.SetColumn(icon, 0);
Grid.SetColumn(textBlock, 1);
Button argsButton = new Button();
argsButton.Content = "参数";
argsButton.Tag = msg as ToolMessageItem;
argsButton.Click += ToolArgsButton_OnClick;
Button resButton = new Button();
resButton.Content = "结果";
resButton.Tag = msg as ToolMessageItem;
resButton.Click += ToolResButton_OnClick;
grid.Children.Add(argsButton);
Grid.SetColumn(argsButton, 2);
grid.Children.Add(resButton);
Grid.SetColumn(resButton, 3);
if (toolMsg.toolParams.ContainsKey("toolName"))
{
grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(36, GridUnitType.Pixel)});
Button checkButton = new Button();
checkButton.Content = "检查";
checkButton.Tag = toolMsg;
checkButton.Click += ToolCheckButton_OnClick;
grid.Children.Add(checkButton);
Grid.SetColumn(checkButton, 4);
}
border.Child = grid;
return border;
}
private void ToolCheckButton_OnClick(object sender, RoutedEventArgs e)
{
try
{
Button button = sender as Button;
ToolMessageItem toolItem = button.Tag as ToolMessageItem;
string gisToolName = toolItem.toolParams["toolName"] as string;
JArray gisToolParams = toolItem.toolParams["toolParams"] as JArray;
List gitToolParamsList = (gisToolParams as JArray).Select(token => token.ToString()).ToList();
Geoprocessing.OpenToolDialog(gisToolName,gitToolParamsList);
}catch (Exception ex)
{
log.Error(ex);
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.Message,"打开工具失败");
}
}
private void ToolArgsButton_OnClick(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
ToolMessageItem toolItem = button.Tag as ToolMessageItem;
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(JsonConvert.SerializeObject(toolItem.toolParams),toolItem.toolName+"工具参数");
}
private void ToolResButton_OnClick(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
ToolMessageItem toolItem = button.Tag as ToolMessageItem;
ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(toolItem.result,toolItem.toolName+"运行结果");
}
private void TestButton_OnClick(object sender, RoutedEventArgs e)
{
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
MessageListItem toolMessageItem = new ToolMessageItem
{
toolName = "toolName",
toolParams = new Dictionary(),
type = MessageType.TOOL_MESSAGE,
status = "success",
content = "JsonConvert.SerializeObject(toolResponse)",
id = (timestamp + 1).ToString(),
role = "user"
};
NewMessage_Recall(toolMessageItem);
}
private void ClearButton_OnClick(object sender, RoutedEventArgs e)
{
idList.Clear();
messageDict.Clear();
borderItemsDict.Clear();
ChatHistoryStackPanel.Children.Clear();
QuestionTextbox.Clear();
StatusTextBlock.Text = "";
}
private void TopButton_OnClick(object sender, RoutedEventArgs e)
{
ScrollViewer.ScrollToTop();
}
private void BottomButton_OnClick(object sender, RoutedEventArgs e)
{
ScrollViewer.ScrollToBottom();
}
private void StopButton_OnClick(object sender, RoutedEventArgs e)
{
Gateway.StopConversation();
StatusTextBlock.Text = "";
}
private void ModelComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
log.Info("ModelComboBox_OnSelectionChanged");
string model = ModelComboBox.SelectedValue.ToString();
log.Info(model);
}
private void QuestionTextbox_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
{
// Shift + Enter: 插入换行
QuestionTextbox.SelectedText = Environment.NewLine;
e.Handled = true;
}
else
{
// Enter: 触发发送
e.Handled = true;
SendButton_OnClick(sender, null);
}
}
}
private void QuestionTextbox_OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
{
// Shift + Enter: 插入换行
QuestionTextbox.SelectedText = Environment.NewLine;
e.Handled = true;
}
else
{
// Enter: 触发发送
e.Handled = true;
SendButton_OnClick(sender, null);
}
}
}
}
}