WPF实现窗体中的悬浮按钮,按钮可拖动,吸附停靠在窗体边缘。

控件XAML代码:

<Button x:Class=\"SunCreate.Common.Controls.FloatButton\"
        ns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
        ns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
        ns:mc=\"http://schemas.open formats.org/markup-compatibility/2006\" 
        ns:d=\"http://schemas.microsoft.com/ /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(  sender, RoutedEventArgs e)
    {
      if (this.Parent != null && this.Parent is  workElement)
      {
         workElement parent = this.Parent as  workElement;
        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(  sender, MouseButtonEventArgs e)
    {
      if (this.Parent != null && this.Parent is  workElement)
      {
         workElement parent = this.Parent as  workElement;
        _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(  sender, RoutedEventArgs e)
    {
      if (_newPos.Equals(_oldPos))
      {
        if (ClickEvent != null)
        {
          ClickEvent(sender, e);
        }
      }
    }
  }
}

如何使用:

<Window
     ns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
     ns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
     ns:ui=\"clr-namespace:SunCreate.Common.Controls;assembly=SunCreate.Common.Controls\"
     ns:d=\"http://schemas.microsoft.com/ /blend/2008\"  ns:mc=\"http://schemas.open formats.org/markup-compatibility/2006\" mc:Ignorable=\"d\" x:Class=\"SunCreate.Common.Controls.Demo.MainWindow\"
     =\"MainWindow\" 
    Height=\"700\" Width=\"1200\" 
    Background=\"#ff10498c\" 
    WindowStartupLocation=\"CenterScreen\">
  <Grid>
    <ui:FloatButton x:Name=\"floatBtn\" ></ui:FloatButton>
  </Grid>
</Window>

效果图:

\"\"

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

收藏 打印