WPF实现窗体中的悬浮按钮
作者:秋荷雨翔 时间:2022-07-25 17:45:53
WPF实现窗体中的悬浮按钮,按钮可拖动,吸附停靠在窗体边缘。
控件XAML代码:
<Button x:Class="SunCreate.Common.Controls.FloatButton"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Width="50" Height="50" Margin="0"
HorizontalAlignment="Left" VerticalAlignment="Top"
x:Name="btn"
Loaded="btn_Loaded" Click="btn_Click" >
<Button.Template>
<ControlTemplate>
<Grid MouseLeftButtonDown="Border_MouseLeftButtonDown">
<Border CornerRadius="25" Background="#022938" Opacity="0.2" >
</Border>
<Border CornerRadius="20" Width="40" Height="40" Background="#022938" Opacity="0.3" >
</Border>
<Border CornerRadius="14" Width="28" Height="28" Background="#b06919" Opacity="0.8" >
</Border>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
控件cs代码:
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.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SunCreate.Common.Controls
{
/// <summary>
/// 悬浮按钮
/// </summary>
public partial class FloatButton : Button
{
public event EventHandler ClickEvent;
private bool _move = false;
double _distance = 200;
double _distanceNew = 5;
private Point _lastPos;
private Point _newPos;
private Point _oldPos;
public FloatButton()
{
InitializeComponent();
}
private void btn_Loaded(object sender, RoutedEventArgs e)
{
if (this.Parent != null && this.Parent is FrameworkElement)
{
FrameworkElement parent = this.Parent as FrameworkElement;
double left = parent.ActualWidth - this.ActualWidth - this._distanceNew;
double top = parent.ActualHeight - this.ActualHeight - this._distanceNew;
this.Margin = new Thickness(left, top, 0, 0);
}
}
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (this.Parent != null && this.Parent is FrameworkElement)
{
FrameworkElement parent = this.Parent as FrameworkElement;
_move = true;
_lastPos = e.GetPosition(parent);
_oldPos = _lastPos;
parent.PreviewMouseMove += (s, ee) =>
{
if (_move)
{
Point pos = ee.GetPosition(parent);
double left = this.Margin.Left + pos.X - this._lastPos.X;
double top = this.Margin.Top + pos.Y - this._lastPos.Y;
this.Margin = new Thickness(left, top, 0, 0);
_lastPos = e.GetPosition(parent);
}
};
parent.PreviewMouseUp += (s, ee) =>
{
if (_move)
{
_move = false;
Point pos = ee.GetPosition(parent);
_newPos = pos;
double left = this.Margin.Left + pos.X - this._lastPos.X;
double top = this.Margin.Top + pos.Y - this._lastPos.Y;
double right = parent.ActualWidth - left - this.ActualWidth;
double bottom = parent.ActualHeight - top - this.ActualHeight;
if (left < _distance && top < _distance) //左上
{
left = this._distanceNew;
top = this._distanceNew;
}
else if (left < _distance && bottom < _distance) //左下
{
left = this._distanceNew;
top = parent.ActualHeight - this.ActualHeight - this._distanceNew;
}
else if (right < _distance && top < _distance) //右上
{
left = parent.ActualWidth - this.ActualWidth - this._distanceNew;
top = this._distanceNew;
}
else if (right < _distance && bottom < _distance) //右下
{
left = parent.ActualWidth - this.ActualWidth - this._distanceNew;
top = parent.ActualHeight - this.ActualHeight - this._distanceNew;
}
else if (left < _distance && top > _distance && bottom > _distance) //左
{
left = this._distanceNew;
top = this.Margin.Top;
}
else if (right < _distance && top > _distance && bottom > _distance) //右
{
left = parent.ActualWidth - this.ActualWidth - this._distanceNew;
top = this.Margin.Top;
}
else if (top < _distance && left > _distance && right > _distance) //上
{
left = this.Margin.Left;
top = this._distanceNew;
}
else if (bottom < _distance && left > _distance && right > _distance) //下
{
left = this.Margin.Left;
top = parent.ActualHeight - this.ActualHeight - this._distanceNew;
}
ThicknessAnimation marginAnimation = new ThicknessAnimation();
marginAnimation.From = this.Margin;
marginAnimation.To = new Thickness(left, top, 0, 0);
marginAnimation.Duration = TimeSpan.FromMilliseconds(200);
Storyboard story = new Storyboard();
story.FillBehavior = FillBehavior.Stop;
story.Children.Add(marginAnimation);
Storyboard.SetTargetName(marginAnimation, "btn");
Storyboard.SetTargetProperty(marginAnimation, new PropertyPath("(0)", Border.MarginProperty));
story.Begin(this);
this.Margin = new Thickness(left, top, 0, 0);
}
};
}
}
private void btn_Click(object sender, RoutedEventArgs e)
{
if (_newPos.Equals(_oldPos))
{
if (ClickEvent != null)
{
ClickEvent(sender, e);
}
}
}
}
}
如何使用:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:SunCreate.Common.Controls;assembly=SunCreate.Common.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="SunCreate.Common.Controls.Demo.MainWindow"
Title="MainWindow"
Height="700" Width="1200"
Background="#ff10498c"
WindowStartupLocation="CenterScreen">
<Grid>
<ui:FloatButton x:Name="floatBtn" ></ui:FloatButton>
</Grid>
</Window>
效果图:
来源:https://www.cnblogs.com/s0611163/p/10002046.html
标签:WPF,窗体,悬浮按钮
0
投稿
猜你喜欢
SpringMVC请求参数的使用总结
2022-11-30 22:23:18
解决spring cloud服务启动之后回到命令行会自动挂掉问题
2022-09-29 13:16:29
WPF+SkiaSharp实现自绘投篮小游戏
2023-09-06 22:59:51
SpringBoot 导出数据生成excel文件返回方式
2023-09-01 11:29:27
解析C#拼接Json串的几种方法
2021-12-28 20:22:48
Unity的IPostprocessBuildWithReport实用案例深入解析
2022-07-29 23:30:15
Handler与Android多线程详解
2022-04-26 18:23:10
C#使用SQL DataAdapter数据适配代码实例
2021-11-29 11:51:15
spring中bean的生命周期详解
2021-11-29 23:31:02
Java分层概念详解
2021-12-12 06:29:18
Android仿QQ微信侧滑删除效果
2023-07-08 11:22:15
浅析Java中comparator接口与Comparable接口的区别
2023-11-01 20:31:14
Android应用中使用ViewPager和ViewPager指示器来制作Tab标签
2021-08-04 11:33:37
深入解析Java多态进阶学习
2022-05-16 16:06:55
Ireport的安装与使用教程
2021-08-08 00:16:43
C#利用QrCode.Net生成二维码(Qr码)的方法
2023-11-30 17:37:38
C++选择排序算法实例
2021-10-27 21:43:33
Android开发中的几种网络请求方式详解
2021-06-01 17:45:21
通过Java带你了解网络IO模型
2022-12-25 10:59:22
C# 泛型集合的自定义类型排序的实现
2022-11-18 20:35:32