更新 App.xaml
以添加 MaterialDesignColors
主题支持,并调整资源字典结构。重命名 chatapi.cs
中的 ChatData
类为 ChatRegisterData
,并新增 ChatData
类以支持聊天消息格式。在 MainWindow.xaml
中更新用户头像路径并重构消息显示布局,使用 Grid
以改善对齐效果。修改 MainWindow.xaml.cs
以适应新的数据结构,并在 chatclient.csproj
中添加应用程序图标及更新资源路径。新增 chat.ico
作为应用程序图标。
This commit is contained in:
parent
778958042d
commit
34d79871dd
@ -1,4 +1,6 @@
|
||||
namespace chatclient.Data
|
||||
using System.Security.RightsManagement;
|
||||
|
||||
namespace chatclient.Data
|
||||
{
|
||||
internal class Server
|
||||
{
|
||||
@ -32,11 +34,16 @@
|
||||
{
|
||||
public string? type { get; set; }
|
||||
}
|
||||
internal class ChatData
|
||||
internal class ChatRegisterData
|
||||
{
|
||||
public string? user { get; set; } = "Unnamed";
|
||||
public string? message { get; set; } = null;
|
||||
public string? image { get; set; } = null;
|
||||
public DateTime timestamp { get; set; } = DateTime.Now;
|
||||
}
|
||||
internal class ChatData
|
||||
{
|
||||
public required string type { get; set; } = "chat";
|
||||
public required string message { get; set; } = "message";
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
<Window x:Class="chatclient.MainWindow"
|
||||
<Window
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:local="clr-namespace:chatclient"
|
||||
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" x:Class="chatclient.MainWindow"
|
||||
mc:Ignorable="d"
|
||||
Title="ChatWindow" Height="450" Width="800" MinHeight="240" MinWidth="380"
|
||||
Style="{StaticResource MaterialDesignWindow}">
|
||||
@ -14,7 +15,7 @@
|
||||
<materialDesign:NavigationRailAssist.FloatingContent>
|
||||
<StackPanel>
|
||||
<Button Style="{StaticResource MaterialDesignFloatingActionMiniLightButton}" Margin="12" >
|
||||
<Image Source="/user.png" />
|
||||
<Image Source="/resource/user.png" />
|
||||
</Button>
|
||||
<TextBlock Text="{Binding Username}"/>
|
||||
</StackPanel>
|
||||
@ -58,35 +59,69 @@
|
||||
<ItemsControl x:Name="messageList">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<materialDesign:Card Margin="0,5" Padding="10"
|
||||
HorizontalAlignment="{Binding Alignment}">
|
||||
<Grid HorizontalAlignment="{Binding Alignment}" Margin="0,5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- 左侧列:头像或空白 -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!-- 中间列:消息卡片 -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- 右侧列:头像或空白 -->
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- 左侧头像(仅当Alignment=Left时显示) -->
|
||||
<Border x:Name="leftAvatar" Grid.Column="0" Width="40" Height="40" Margin="10,0,10,0" CornerRadius="20" VerticalAlignment="Top">
|
||||
<!-- 图片头像 -->
|
||||
<Image Source="{Binding Image}" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="20,20" RadiusX="20" RadiusY="20"/>
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
</Border>
|
||||
<!-- 消息卡片(始终在中间列) -->
|
||||
<materialDesign:Card Grid.Column="1" Padding="10" HorizontalAlignment="{Binding Alignment}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding Sender}" FontWeight="Bold"
|
||||
Foreground="{Binding SenderColor}"/>
|
||||
<TextBlock Text="{Binding Content}" TextWrapping="Wrap"
|
||||
Margin="0,5,0,0"/>
|
||||
<TextBlock Text="{Binding Timestamp, StringFormat='HH:mm:ss'}"
|
||||
Foreground="Gray" FontSize="10"
|
||||
HorizontalAlignment="Right" Margin="0,5,0,0"/>
|
||||
<TextBlock Text="{Binding Sender}" FontWeight="Bold" Foreground="{Binding SenderColor}"/>
|
||||
<TextBlock Text="{Binding Content}" TextWrapping="Wrap" Margin="0,5,0,0"/>
|
||||
<TextBlock Text="{Binding Timestamp, StringFormat='HH:mm:ss'}" Foreground="Gray" FontSize="10" HorizontalAlignment="Right" Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</materialDesign:Card>
|
||||
<!-- 右侧头像(仅当Alignment=Right时显示) -->
|
||||
<Border x:Name="rightAvatar" Grid.Column="2" Width="40" Height="40" Margin="10,0,10,0" CornerRadius="20" VerticalAlignment="Top">
|
||||
<Image Source="{Binding Image}" Stretch="UniformToFill" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image.Clip>
|
||||
<EllipseGeometry Center="20,20" RadiusX="20" RadiusY="20"/>
|
||||
</Image.Clip>
|
||||
</Image>
|
||||
</Border>
|
||||
</Grid>
|
||||
<!-- 根据Alignment显示正确的头像 -->
|
||||
<DataTemplate.Triggers>
|
||||
<!-- 左对齐消息:显示左侧头像 -->
|
||||
<DataTrigger Binding="{Binding Alignment}" Value="Left">
|
||||
<Setter TargetName="leftAvatar" Property="Visibility" Value="Visible"/>
|
||||
<Setter TargetName="rightAvatar" Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
<!-- 右对齐消息:显示右侧头像 -->
|
||||
<DataTrigger Binding="{Binding Alignment}" Value="Right">
|
||||
<Setter TargetName="leftAvatar" Property="Visibility" Value="Collapsed"/>
|
||||
<Setter TargetName="rightAvatar" Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- 输入区域 -->
|
||||
<Grid Grid.Row="2" Margin="0,5,0,0">
|
||||
<Grid Grid.Row="2" Background="{DynamicResource MaterialDesign.Brush.Primary.Foreground}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox x:Name="txtMessage" Grid.Column="0" Margin="0,0,5,0"
|
||||
<TextBox x:Name="txtMessage" Grid.Column="0"
|
||||
materialDesign:HintAssist.Hint="输入消息..."
|
||||
AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
|
||||
TextWrapping="Wrap" MinHeight="60" MaxHeight="120"
|
||||
KeyDown="MessageInput_KeyDown"/>
|
||||
TextWrapping="Wrap" MinHeight="60" MaxHeight="120" Margin="5"/>
|
||||
|
||||
<Button x:Name="btnSend" Grid.Column="1" Content="发送" MinWidth="80"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}"
|
||||
|
@ -165,22 +165,22 @@ namespace chatclient
|
||||
}
|
||||
else if (Type.type == "chat")
|
||||
{
|
||||
var chat = JsonSerializer.Deserialize<ChatData>(msg);
|
||||
var chat = JsonSerializer.Deserialize<ChatRegisterData>(msg);
|
||||
if (chat != null)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
// 处理聊天消息
|
||||
var chatmessage = new ChatMessage
|
||||
{
|
||||
Sender = chat.user ?? "未知用户",
|
||||
Type = MessageType.Text,
|
||||
Image = new BitmapImage(new Uri(chat.image ?? "pack://application:,,,/user.png", UriKind.Absolute)),
|
||||
Image = new BitmapImage(new Uri(chat.image ?? "pack://application:,,,/resource/user.png", UriKind.Absolute)),
|
||||
Content = chat.message ?? "无内容",
|
||||
Timestamp = chat.timestamp,
|
||||
Alignment = HorizontalAlignment.Left,
|
||||
SenderColor = new SolidColorBrush(Colors.Black)
|
||||
};
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
|
||||
mainWindow?.Messages.Add(chatmessage);
|
||||
});
|
||||
@ -224,25 +224,49 @@ namespace chatclient
|
||||
{
|
||||
Sender = "我",
|
||||
Type = MessageType.Text,
|
||||
Image = new BitmapImage(new Uri("pack://application:,,,/user.png", UriKind.Absolute)), // 默认头像
|
||||
Image = new BitmapImage(new Uri("pack://application:,,,/resource/user.png", UriKind.Absolute)), // 默认头像
|
||||
Content = txtMessage.Text,
|
||||
Timestamp = DateTime.Now,
|
||||
Alignment = HorizontalAlignment.Right, // 自己发送的消息靠右
|
||||
SenderColor = new SolidColorBrush(Colors.Blue)
|
||||
};
|
||||
var newChatMessage = new ChatData
|
||||
{
|
||||
type = "chat",
|
||||
message = newMessage.Content
|
||||
};
|
||||
string ChatJsonData = JsonSerializer.Serialize(newChatMessage);
|
||||
byte[] dataBytes = Encoding.UTF8.GetBytes(ChatJsonData);
|
||||
log.Info($"向服务器聊天信息(长度:{dataBytes.Length})");
|
||||
if (Client != null)
|
||||
{
|
||||
if (Client.Connected)
|
||||
{
|
||||
Client.Send(dataBytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
log.Info("未连接服务器,尝试连接");
|
||||
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
Client.Connect(IPAddress.Parse(Server.ServerIP), Server.ServerPort);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(ex);
|
||||
Client.Close();
|
||||
}
|
||||
//finally
|
||||
//{
|
||||
//
|
||||
//}
|
||||
}
|
||||
}
|
||||
// 添加到消息列表
|
||||
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; // 阻止换行
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,9 +6,23 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>resource\chat.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="resource\chat.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="2.0.1" />
|
||||
<PackageReference Include="log4net" Version="3.1.0" />
|
||||
<PackageReference Include="MaterialDesignThemes" Version="5.2.1" />
|
||||
<PackageReference Include="MaterialDesignThemes.MahApps" Version="5.2.1" />
|
||||
@ -16,7 +30,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="user.png" />
|
||||
<Resource Include="resource\user.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
BIN
chatclient/resource/chat.ico
Normal file
BIN
chatclient/resource/chat.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
Loading…
x
Reference in New Issue
Block a user