WPF实现窗体中的悬浮按钮,按钮可拖动,吸附停靠在窗体边缘。
控件XAML代码:
< Button x:Class = "SunCreate.Common.Controls.FloatButton"
xmlns = "http://schemas.microsoft测试数据/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft测试数据/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft测试数据/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测试数据/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft测试数据/winfx/2006/xaml"
xmlns:ui = "clr-namespace:SunCreate.Common.Controls;assembly=SunCreate.Common.Controls"
xmlns:d = "http://schemas.microsoft测试数据/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://HdhCmsTestcnblogs测试数据/s0611163/p/10002046.html
dy("nrwz");