溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

WPF實(shí)現(xiàn)窗體中的懸浮按鈕

發(fā)布時(shí)間:2020-09-03 01:35:53 來源:腳本之家 閱讀:186 作者:秋荷雨翔 欄目:編程語言

WPF實(shí)現(xiàn)窗體中的懸浮按鈕,按鈕可拖動(dòng),吸附??吭诖绑w邊緣。

控件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實(shí)現(xiàn)窗體中的懸浮按鈕

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI