温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WPF实现窗体中的悬浮按钮

发布时间:2020-09-03 01:35:53 来源:脚本之家 阅读:187 作者:秋荷雨翔 栏目:编程语言

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实现窗体中的悬浮按钮

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI