在WPF中,Popup是一个可弹出并显示内容的控件,当它显示的时候,始终会显示在UI的最上方,利用这一特性,我们可以扩展它的功能。首先,新建一个用户控件去继承popup控件,前端代码如下:
<Popup x:Class="FilesManager.Dialog.PopupBox"
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:FilesManager.Dialog"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Border x:Name="border" Background="Gray" CornerRadius="8" MinHeight="35" Width="400" Height="100">
<TextBlock TextWrapping="WrapWithOverflow"
Foreground="White"
Margin="10"
FontSize="18"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Path=Message,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:PopupBox}},UpdateSourceTrigger=PropertyChanged}">
</TextBlock>
</Border>
</Grid>
</Popup>
然后是后端代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace FilesManager.Dialog
{
/// <summary>
/// PopupBox.xaml 的交互逻辑
/// </summary>
public partial class PopupBox : Popup
{
public PopupBox()
{
InitializeComponent();
border.MouseUp += (s, e) => { this.IsOpen = false; };
}
public new double Opacity
{
get { return (double)GetValue(OpacityProperty); }
set { SetValue(OpacityProperty, value); }
}
public static new readonly DependencyProperty OpacityProperty =
DependencyProperty.Register("Opacity", typeof(double), typeof(PopupBox), new PropertyMetadata(1.0,new PropertyChangedCallback(OnOpacityPropertyChangedCallback)));
private static void OnOpacityPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is PopupBox source)) return;
if (!(e.NewValue is double v)) return;
source.border.Opacity = v;
}
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(PopupBox), new PropertyMetadata(string.Empty));
private static PopupBox dialog = new PopupBox();
private static DispatcherTimer timer = new DispatcherTimer();
public static void Show(Window owner,string v,int seconds = 1)
{
try
{
Application.Current.Dispatcher.Invoke(() =>
{
dialog.Message = v;
dialog.PlacementTarget = owner;
dialog.Placement = PlacementMode.Center;
dialog.StaysOpen = true;
dialog.AllowsTransparency = true;
dialog.VerticalOffset = owner.ActualHeight / 3 - 45;
dialog.Opacity = 0.9;
dialog.IsOpen = true;
timer.Tick -= Timer_Tick;
timer.Tick += Timer_Tick;
timer.Interval = new TimeSpan(0, 0, seconds);
timer.Start();
});
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void Timer_Tick(object sender, EventArgs e)
{
timer.Stop();
Task.Run(() =>
{
try
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(5);
Application.Current.Dispatcher.Invoke(() =>
{
dialog.Opacity -= 0.01;
});
}
Application.Current.Dispatcher.Invoke(() =>
{
dialog.IsOpen = false;
dialog.Message = String.Empty;
});
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
});
}
}
}