软件编程
位置:首页>> 软件编程>> C#编程>> WPF实现窗体中的悬浮按钮

WPF实现窗体中的悬浮按钮

作者:秋荷雨翔  发布时间:2022-07-25 17:45:53 

标签:WPF,窗体,悬浮按钮

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>

效果图:

WPF实现窗体中的悬浮按钮

来源:https://www.cnblogs.com/s0611163/p/10002046.html

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com