diff --git a/chatclient/Data/ChatDataModel.cs b/chatclient/Data/ChatDataModel.cs
new file mode 100644
index 0000000..27b02d2
--- /dev/null
+++ b/chatclient/Data/ChatDataModel.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows;
+using System.Windows.Media.Imaging;
+
+namespace chatclient.Data
+{
+ ///
+ /// 聊天消息类,表示一条消息的内容和显示属性
+ ///
+ public class ChatMessage
+ {
+ ///
+ /// 发送者名称
+ ///
+ public required string Sender { get; set; }
+ ///
+ /// 消息类型(文本、图片、文件、系统消息等)
+ ///
+ public required MessageType Type { get; set; } = MessageType.Text;
+ ///
+ /// 消息发送者的头像图片
+ ///
+ public required BitmapImage Image { get; set; }
+ ///
+ /// 消息内容
+ ///
+ public required string Content { get; set; }
+ ///
+ /// 消息发送时间
+ ///
+ public DateTime Timestamp { get; set; }
+ ///
+ /// 消息在界面中的对齐方式(左/右)
+ ///
+ public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
+ ///
+ /// 发送者名称的显示颜色
+ ///
+ public Brush SenderColor { get; set; } = Brushes.Black;
+ }
+ public enum MessageType
+ {
+ Text,
+ Image,//图片
+ File,//文件
+ System//系统信息
+ }
+}
diff --git a/chatclient/chatapi.cs b/chatclient/Data/chatapi.cs
similarity index 97%
rename from chatclient/chatapi.cs
rename to chatclient/Data/chatapi.cs
index c5c3e56..4d36103 100644
--- a/chatclient/chatapi.cs
+++ b/chatclient/Data/chatapi.cs
@@ -1,5 +1,4 @@
-
-namespace chatapi
+namespace chatclient.Data
{
internal class Server
{
diff --git a/chatclient/LoginWindow.xaml.cs b/chatclient/LoginWindow.xaml.cs
index 603a59a..63c32d5 100644
--- a/chatclient/LoginWindow.xaml.cs
+++ b/chatclient/LoginWindow.xaml.cs
@@ -6,9 +6,9 @@ using System.Threading.Tasks;
using System.Windows;
using System.Net.Sockets;
using log4net;
-using chatapi;
using System.Net.Http;
using Microsoft.Win32;
+using chatclient.Data;
namespace chatclient
@@ -126,7 +126,7 @@ namespace chatclient
string SignJsonData = JsonSerializer.Serialize(SignData);
byte[] dataBytes = Encoding.UTF8.GetBytes(SignJsonData);
var content = new StringContent(SignJsonData, Encoding.UTF8, "application/json");
- var response = await MainWindow.HttpClient.PostAsync($"{chatapi.Server.ServerUrl}/api/register", content);
+ var response = await MainWindow.HttpClient.PostAsync($"{Server.ServerUrl}/api/register", content);
var responseBody = await response.Content.ReadAsStringAsync();
log.Info($"注册请求已发送,响应内容: {responseBody}");
var signresponse = JsonSerializer.Deserialize(responseBody);
diff --git a/chatclient/MainWindow.xaml b/chatclient/MainWindow.xaml
index 4ff422e..18a8066 100644
--- a/chatclient/MainWindow.xaml
+++ b/chatclient/MainWindow.xaml
@@ -27,7 +27,72 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chatclient/MainWindow.xaml.cs b/chatclient/MainWindow.xaml.cs
index 6d64d54..a914167 100644
--- a/chatclient/MainWindow.xaml.cs
+++ b/chatclient/MainWindow.xaml.cs
@@ -1,7 +1,6 @@
using System.Text;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
@@ -17,11 +16,11 @@ using System.Security.Policy;
using log4net;
using log4net.Config;
using System.Text.Json;
-using chatapi;
-using System.Diagnostics;
-using System.Windows.Interop;
-using ControlzEx.Standard;
+using chatclient.Data;
using System.ComponentModel;
+using System.Collections.ObjectModel;
+using System.Windows.Threading;
+using System.Collections.Specialized;
[assembly: XmlConfigurator(ConfigFile = "config/log4net.config", Watch = true)]
namespace chatclient
@@ -38,7 +37,7 @@ namespace chatclient
public static Socket? Client;
public static readonly HttpClient HttpClient = new HttpClient();
public event PropertyChangedEventHandler? PropertyChanged;
- private string? _Username;
+ private string? _Username;
public string? Username
{
get { return _Username; }
@@ -48,6 +47,10 @@ namespace chatclient
Update("Username");
}
}
+ // 消息列表
+ public ObservableCollection Messages { get; } = new ObservableCollection();
+ private ItemsControl MessageList => messageList;
+ private ScrollViewer MessageScroller => messageScroller;
private void Update(string UpdateName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(UpdateName));
@@ -72,8 +75,16 @@ namespace chatclient
Login.Show();
Thread th = new Thread(Receive);
th.Start();
+ MessageList.ItemsSource = Messages;
+ ((INotifyCollectionChanged)MessageList.Items).CollectionChanged += (s, e) =>
+ {
+ // 确保有足够的时间让UI更新
+ Dispatcher.BeginInvoke(new Action(() =>
+ {
+ MessageScroller.ScrollToEnd();
+ }), DispatcherPriority.ContextIdle);
+ };
}
-
static void Receive()
{
byte[] buffer = new byte[1024];
@@ -129,26 +140,41 @@ namespace chatclient
}
});
}
- else if (LoginResponse != null)
- {
- log.Warn($"登录失败: {LoginResponse.message}\nMsg:{msg}");
- var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
- loginWindow!.LoginMsg = LoginResponse.message;
- }
- }
- else if (Type.type == "login_0")
- {
- if (LoginResponse != null)
- {
- var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
- loginWindow!.LoginMsg = LoginResponse.message;
- }
else
{
- var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
- loginWindow!.LoginMsg = "服务器返回错误";
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
+ if (loginWindow != null)
+ {
+ loginWindow.LoginMsg = LoginResponse != null ? LoginResponse.message : "服务器返回错误";
+ }
+ });
}
}
+ else if(Type.type == "login_0" && LoginResponse != null)
+ {
+ log.Warn($"登录失败: {LoginResponse.message}\nMsg:{msg}");
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
+ if (loginWindow != null)
+ {
+ loginWindow.LoginMsg = LoginResponse.message;
+ }
+ });
+ }
+ else
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ var loginWindow = Application.Current.Windows.OfType().FirstOrDefault();
+ if (loginWindow != null)
+ {
+ loginWindow.LoginMsg = LoginResponse != null ? LoginResponse.message : "服务器返回错误";
+ }
+ });
+ }
}
}
catch (JsonException ex)
@@ -160,5 +186,44 @@ namespace chatclient
log.Error("处理响应时发生错误", ex);
}
}
+ private void SendMessage_Click(object sender, RoutedEventArgs e)
+ {
+ SendMessage();
+ }
+ private void SendMessage()
+ {
+ if (string.IsNullOrWhiteSpace(txtMessage.Text))
+ return;
+
+ // 获取当前选中的联系人
+ //var contact = cmbContacts.SelectedItem as Contact;
+ // 判断是否为群组,若是则收件人设为“所有人”,否则为联系人显示名
+ //string recipient = contact?.IsGroup == true ? "所有人" : contact?.DisplayName;
+
+ // 创建新消息
+ var newMessage = new ChatMessage
+ {
+ Sender = "我",
+ Type = MessageType.Text,
+ Image = new BitmapImage(new Uri("pack://application:,,,/user.png", UriKind.Absolute)), // 默认头像
+ Content = txtMessage.Text,
+ Timestamp = DateTime.Now,
+ Alignment = HorizontalAlignment.Right, // 自己发送的消息靠右
+ SenderColor = new SolidColorBrush(Colors.Blue)
+ };
+ // 添加到消息列表
+ Messages.Add(newMessage);
+ // 清空输入框
+ txtMessage.Clear();
+ }
+ // 消息输入框回车事件
+ private void MessageInput_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Enter && Keyboard.Modifiers != ModifierKeys.Shift)
+ {
+ SendMessage();
+ e.Handled = true; // 阻止换行
+ }
+ }
}
}
\ No newline at end of file