优化菜单样式和异步加载逻辑
在 `MaterialTrayMenuItem.xaml` 中添加命名空间,更新菜单项样式,增加悬停和点击动画效果,提升用户交互体验。新增上下文菜单样式,包含透明度和缩放动画。 在 `LoginWindow.xaml.cs` 中将 `Window_Loaded` 方法改为异步,增强窗口加载时的连接稳定性,并添加连接服务器的逻辑及错误处理。 在 `MainWindow.xaml` 中移除 `TextBox` 控件的 `Foreground` 属性设置,简化样式,保持界面整洁。
This commit is contained in:
parent
f4e2d0be38
commit
6364f5f4d1
@ -1,7 +1,12 @@
|
|||||||
<ResourceDictionary
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes">
|
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">
|
||||||
|
<!-- 动画缓动函数 -->
|
||||||
|
<CubicEase x:Key="MenuEase" EasingMode="EaseOut"/>
|
||||||
<!-- Material Design 托盘菜单样式 -->
|
<!-- Material Design 托盘菜单样式 -->
|
||||||
<Style x:Key="MaterialTrayMenuItem" TargetType="MenuItem" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
<Style x:Key="MaterialTrayMenuItem" TargetType="MenuItem" BasedOn="{StaticResource MaterialDesignMenuItem}">
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
@ -13,27 +18,81 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="MenuItem">
|
<ControlTemplate TargetType="MenuItem">
|
||||||
<Border x:Name="Border"
|
<Border x:Name="Border"
|
||||||
Background="Transparent"
|
|
||||||
CornerRadius="4"
|
CornerRadius="4"
|
||||||
SnapsToDevicePixels="True">
|
SnapsToDevicePixels="True"
|
||||||
|
Background="Transparent">
|
||||||
<Grid>
|
<Grid>
|
||||||
<materialDesign:Ripple Content="{TemplateBinding Header}" Background="Transparent" Foreground="{TemplateBinding Foreground}"
|
<!-- 背景动画层 -->
|
||||||
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Center" Padding="{TemplateBinding Padding}"/>
|
<Rectangle x:Name="HoverRect"
|
||||||
|
Fill="#FF3D3D40"
|
||||||
|
Opacity="0"
|
||||||
|
RadiusX="4" RadiusY="4"/>
|
||||||
|
|
||||||
|
<!-- 涟漪效果层 -->
|
||||||
|
<materialDesign:Ripple
|
||||||
|
x:Name="Ripple"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
Content="{TemplateBinding Header}"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Padding="{TemplateBinding Padding}"
|
||||||
|
Background="Transparent"
|
||||||
|
HorizontalContentAlignment="Stretch"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<ControlTemplate.Triggers>
|
<ControlTemplate.Triggers>
|
||||||
<Trigger Property="IsHighlighted" Value="True">
|
<!-- 悬停动画 -->
|
||||||
<Setter TargetName="Border" Property="Background" Value="{DynamicResource MaterialDesignSelection}"/>
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetName="HoverRect"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0.2"
|
||||||
|
Duration="0:0:0.2"
|
||||||
|
EasingFunction="{StaticResource MenuEase}"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetName="HoverRect"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0"
|
||||||
|
Duration="0:0:0.3"
|
||||||
|
EasingFunction="{StaticResource MenuEase}"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
</Trigger>
|
</Trigger>
|
||||||
|
|
||||||
|
<!-- 点击动画 -->
|
||||||
|
<EventTrigger RoutedEvent="PreviewMouseDown">
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetName="Ripple"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0.5" To="1"
|
||||||
|
Duration="0:0:0.15"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</EventTrigger>
|
||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<!-- 托盘菜单样式 -->
|
||||||
<Style x:Key="MaterialTrayMenu" TargetType="ContextMenu">
|
<Style x:Key="MaterialTrayMenu" TargetType="ContextMenu">
|
||||||
|
<!--<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>-->
|
||||||
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
|
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignDivider}"/>
|
<Setter Property="BorderBrush" Value="#A0252526"/>
|
||||||
<Setter Property="BorderThickness" Value="1"/>
|
<Setter Property="BorderThickness" Value="2"/>
|
||||||
<Setter Property="Padding" Value="8"/>
|
<Setter Property="Padding" Value="8"/>
|
||||||
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
<Setter Property="SnapsToDevicePixels" Value="True"/>
|
||||||
<Setter Property="Effect">
|
<Setter Property="Effect">
|
||||||
@ -41,5 +100,57 @@
|
|||||||
<DropShadowEffect BlurRadius="16" ShadowDepth="4" Color="#40000000"/>
|
<DropShadowEffect BlurRadius="16" ShadowDepth="4" Color="#40000000"/>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
|
<Setter Property="RenderTransformOrigin" Value="0.5 0.5"/>
|
||||||
|
<Setter Property="RenderTransform">
|
||||||
|
<Setter.Value>
|
||||||
|
<ScaleTransform ScaleY="0.9"/>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ContextMenu">
|
||||||
|
<Border x:Name="MenuBorder"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
CornerRadius="4"
|
||||||
|
Padding="{TemplateBinding Padding}">
|
||||||
|
<ItemsPresenter/>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsOpen" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<!-- 透明度动画 -->
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
From="0" To="1"
|
||||||
|
Duration="0:0:0.2"/>
|
||||||
|
|
||||||
|
<!-- 仅保留缩放动画(无位移) -->
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetProperty="RenderTransform.ScaleY"
|
||||||
|
From="0.9" To="1"
|
||||||
|
Duration="0:0:0.3"
|
||||||
|
EasingFunction="{StaticResource MenuEase}"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
To="0"
|
||||||
|
Duration="0:0:0.15"/>
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
@ -277,10 +277,28 @@ namespace chatclient
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public void Window_Loaded(object sender, RoutedEventArgs e)
|
public async void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
log.Info("登录窗口已加载");
|
log.Info("登录窗口已加载");
|
||||||
|
if (MainWindow.Client?.Connected == false)
|
||||||
|
{
|
||||||
|
log.Info("未连接服务器,尝试连接");
|
||||||
|
// 异步连接操作
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MainWindow.Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
MainWindow.Client?.Connect(IPAddress.Parse(Server.ServerIP), Server.ServerPort);
|
||||||
|
MainWindow.StartReceive();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error($"连接失败: {ex.Message}");
|
||||||
|
MainWindow.Client?.Close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string tempPath = System.IO.Path.GetTempPath();
|
string tempPath = System.IO.Path.GetTempPath();
|
||||||
@ -323,7 +341,7 @@ namespace chatclient
|
|||||||
log.Error("保存登录信息到临时文件失败", ex);
|
log.Error("保存登录信息到临时文件失败", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MainWindow.token == null) Application.Current.Shutdown();
|
if (MainWindow.token == null) Application.Current.Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@
|
|||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBox x:Name="txtMessage" Grid.Row="0" materialDesign:HintAssist.Hint="输入消息..." AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
|
<TextBox x:Name="txtMessage" Grid.Row="0" materialDesign:HintAssist.Hint="输入消息..." AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
|
||||||
TextWrapping="Wrap" MinHeight="50" MaxHeight="100" Margin="5" BorderBrush="#00000000" CaretBrush="#00673AB7" SelectionBrush="#00B39DDB"/>
|
TextWrapping="Wrap" MinHeight="50" MaxHeight="100" Margin="5" BorderBrush="#00000000"/>
|
||||||
<Button x:Name="btnSend" Grid.Row="1" Content="发送" MinWidth="80" Style="{StaticResource MaterialDesignRaisedButton}"
|
<Button x:Name="btnSend" Grid.Row="1" Content="发送" MinWidth="80" Style="{StaticResource MaterialDesignRaisedButton}"
|
||||||
Click="SendMessage_Click" Width="20" HorizontalAlignment="Right" Margin="2,2,4,4"/>
|
Click="SendMessage_Click" Width="20" HorizontalAlignment="Right" Margin="2,2,4,4"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user