WPF 用鼠标移动元素

2023-12-13

我正在尝试在 WPF 应用程序中用鼠标移动按钮。

XAML Grid 是结构的根:

<Grid Name="MyGrid"            >
    <Button Name="Samplebutton"
            PreviewMouseDown="Samplebutton_PreviewMouseDown"
            PreviewMouseUp="Samplebutton_PreviewMouseUp"
            PreviewMouseMove="Samplebutton_PreviewMouseMove"
            Content="Moving" Width="100" Height="35"/>
</Grid>

和后面的代码:

private bool _isMoving;


private void Samplebutton_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    _isMoving = true;
}

private void Samplebutton_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
    _isMoving = false;
}

private void Samplebutton_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_isMoving) return;

    TranslateTransform transform = new TranslateTransform();
    transform.X = Mouse.GetPosition(MyGrid).X;
    transform.Y = Mouse.GetPosition(MyGrid).Y;
    this.Samplebutton.RenderTransform = transform;
}

第一次点击按钮将他移到很远的地方,然后我可以移动按钮,但这是第一次按钮被移开。我缺少什么?


这是一个旧帖子,但是(我认为)这是一个更好的方法:

我认为你不应该使用布尔值来检查鼠标是否正在拖动当前控件。另外,使用PreviewMouse....是获取鼠标位置的无用修复(当鼠标不在控件上方时)

你应该捕获鼠标。当您捕获鼠标时,即使鼠标不在控件上方,仍然会引发 mouse_move 事件(即使关闭当前窗口)。我认为这才是应该做的。它更简单、更容易阅读。

这是代码:

public partial class VisualBlock : UserControl
{
    private Point _positionInBlock;

    public VisualBlock()
    {
        InitializeComponent();
    }

    private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
    {
        // when the mouse is down, get the position within the current control. (so the control top/left doesn't move to the mouse position)
        _positionInBlock = Mouse.GetPosition(this);

        // capture the mouse (so the mouse move events are still triggered (even when the mouse is not above the control)
        this.CaptureMouse();
    }

    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        // if the mouse is captured. you are moving it. (there is your 'real' boolean)
        if (this.IsMouseCaptured)
        {
            // get the parent container
            var container = VisualTreeHelper.GetParent(this) as UIElement;

            if(container == null)
                return;
            
            // get the position within the container
            var mousePosition = e.GetPosition(container);

            // move the usercontrol.
            this.RenderTransform = new TranslateTransform(mousePosition.X - _positionInBlock.X, mousePosition.Y - _positionInBlock.Y);
        }
    }

    private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
    {
        // release this control.
        this.ReleaseMouseCapture();
    }
}

Update:

如果您有一个窗口,例如带有画布,则可以将此用户控件添加到画布中。

这是它的要点:WPF 移动控件


<Window x:Class="WPFTestControlMoveMouse.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFTestControlMoveMouse"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Button Grid.Row="0" Click="Button_Click">New</Button>
        <Canvas x:Name="MyCanvas" Grid.Row="1"></Canvas>
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFTestControlMoveMouse
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MyCanvas.Children.Add(new VisualBlock());
        }
    }
}

<UserControl x:Class="WPFTestControlMoveMouse.VisualBlock"
             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" 
             xmlns:local="clr-namespace:WPFTestControlMoveMouse"
             mc:Ignorable="d" 
             Width="300" Height="200" MouseDown="UserControl_MouseDown" MouseUp="UserControl_MouseUp" MouseMove="UserControl_MouseMove">
    <Grid>
        <Border BorderBrush="Black" BorderThickness="1" Background="Silver" />
        <TextBlock FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center">Hi there!!</TextBlock>
    </Grid>
</UserControl>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFTestControlMoveMouse
{
    /// <summary>
    /// Interaction logic for VisualBlock.xaml
    /// </summary>
    public partial class VisualBlock : UserControl
    {
        private Point _positionInBlock;

        public VisualBlock()
        {
            InitializeComponent();
        }

        private void UserControl_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // when the mouse is down, get the position within the current control. (so the control top/left doesn't move to the mouse position)
            _positionInBlock = Mouse.GetPosition(this);

            // capture the mouse (so the mouse move events are still triggered (even when the mouse is not above the control)
            this.CaptureMouse();
        }

        private void UserControl_MouseMove(object sender, MouseEventArgs e)
        {
            // if the mouse is captured. you are moving it. (there is your 'real' boolean)
            if (this.IsMouseCaptured)
            {
                // get the parent container
                var container = VisualTreeHelper.GetParent(this) as UIElement;

                // get the position within the container
                var mousePosition = e.GetPosition(container);

                // move the usercontrol.
                this.RenderTransform = new TranslateTransform(mousePosition.X - _positionInBlock.X, mousePosition.Y - _positionInBlock.Y);
            }
        }

        private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
        {
            // release this control.
            this.ReleaseMouseCapture();
        }
    }
}

通过从标签控件派生来用鼠标移动标签:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WPFTestControlMoveMouse
{
    public class MyLabel : Label
    {
        private Point _positionInBlock;

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            // when the mouse is down, get the position within the current control. (so the control top/left doesn't move to the mouse position)
            _positionInBlock = Mouse.GetPosition(this);

            // capture the mouse (so the mouse move events are still triggered (even when the mouse is not above the control)
            this.CaptureMouse();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            // if the mouse is captured. you are moving it. (there is your 'real' boolean)
            if (this.IsMouseCaptured)
            {
                // get the parent container
                var container = VisualTreeHelper.GetParent(this) as UIElement;

                // get the position within the container
                var mousePosition = e.GetPosition(container);

                // move the usercontrol.
                this.RenderTransform = new TranslateTransform(mousePosition.X - _positionInBlock.X, mousePosition.Y - _positionInBlock.Y);
            }
        }
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            // release this control.
            this.ReleaseMouseCapture();
        }

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF 用鼠标移动元素 的相关文章

随机推荐

  • R:在带有多行命令的 system() 中使用 wait=FALSE

    我有一个长时间运行的进程 用 Java 编写 我希望与 system wait FALSE 异步运行 为了能够确定进程何时结束 我想根据中给出的建议创建一个文件如何确定以 system wait FALSE 启动的进程何时结束 问题是 等待
  • 在Python中提取列表元素

    这是我的第一个Python程序 我使用下面的代码来生成给定范围的组合 for k in range 0 items 1 for r in range 0 items 1 if r k gt 0 res x for x in itertool
  • 检查产品是否在愿望清单中

    我正在开发 Magento 主题 我需要构建一个函数来检查产品是否已添加到用户的愿望清单中 Magento 有一个 Mage Wishlist Helper Data 帮助程序类 但我不知道如何构建一个检查是否已在愿望清单中的函数 基本上我
  • OctoberCMS 如何重写用户插件的 onRegister() 函数?

    我在用着十月CMS基于 Laravel 我正在尝试覆盖用户插件 onRegister 功能 之前的答案帮助我扩展了插件 我想将用户名限制为字母数字alpha dash并限制为 50 个字符 原来的函数在帐户 php public funct
  • 这是 Javascript 中有效的 monad 转换器吗?

    为了更好地理解 monad 转换器 我实现了一个 由于 Javascript 是动态类型的 所以我不会模仿类型或数据构造函数 而是仅声明普通的旧 Javascript 对象 这些对象包含相应的静态函数以形成特定的 monad 转换器 基本思
  • PySpark reduceByKey 对多个值的影响

    如果我有一个 K V 对 如下所示 K v1 v2 K v3 v4 我怎样才能总结出我得到的值 k v1 v3 v2 v4 reduceByKey 支持函数 假设 A 是键值对的数组 output A reduceByKey lambda
  • ggplot2 - 饼图 - 以相反顺序的值标签

    我正在尝试使用 ggplot2 将标签与饼图匹配 Code values c 59 4 4 11 26 labels c catA catB catC catD catE pos cumsum values values 2 graph l
  • 使用 Flexjson 更改属性名称

    我使用 FlexJson 进行序列化 唯一的问题是它生成小写的字段名称 而我需要它们以大写开头 class Person String name public String getName return name 序列化时 该字段被序列化为
  • 如何拦截rails的模板渲染

    我有一个为多个网站提供服务的应用程序 与 Stack Exchange 类似 这几个站点的行为非常相似 给定以下视图目录结构 views shared users index html erb app1 users index html e
  • 不同电脑的渲染问题

    所以我正在制作一个塔防游戏 我与他们共享了一个构建 这样我就可以检查一切是否在另一台主机上正常运行 实际发生的情况是 虽然一切在我这边都完美渲染 在我的 mac xcode windows visual studio 2012 上 但在我朋
  • 如何按表中的“数字”位置选择列?

    我试图通过表中的 x 位置来选择列 DBI my example hookup gt prepare qq SELECT This That Condition I also want COLUMN 10 FROM tbl LIMIT co
  • 将数据传递到 Angular 4 中的自定义组件

    我有一个带有选择器的自定义组件 我如何以角度4将数据传递给它以在其模板中显示数据 喜欢
  • 如何按名称导入自定义Python包

    我创建了一个名为 custom module 的文件夹 并且该文件夹内有 init py 其中包含 all Submodule1 Submodule2 从我读到的文档中我应该能够调用import custom module并访问该包 但这并
  • FLAG_ACTIVITY_REORDER_TO_FRONT 和 startActivityForResult

    Activity A 使用 startActivityForResult 启动 B B 使用 startActivity 启动 C 之后的活动栈就是A B C 现在假设 C 使用 FLAG ACTIVITY REORDER TO FRONT
  • MongoDB - 全文索引 - 全文搜索 - 词干提取

    我注意到 如果我在某个集合的启用全文搜索的字符串字段中输入值 seasons 那么当我查询 season 时 MongoDB 会找到该值 但如果我输入更复杂的内容 例如 mice 或 criteria 当我分别查询 mouse 或 crit
  • 如何使用内容脚本有效地覆盖 CSS?

    我的问题是我想覆盖网站的样式 问题是 有一种方法可以做到这一点 使用 important句子 如所见这个例子 但是 我的文件中有数千条 CSS 指令 是否有更快速 有效的方法来执行此操作 即不放置 important在每一行上 我发现最简单
  • 如何使用 C#/WPF 在 MouseEnter 和 MouseLeave 事件上对 ListBox 项目进行动画处理?

    我无法通过列表项的 C 代码捕获 触发 OnMouseEnter 或 OnMouseLeave 事件 需要明确的是 我不需要 OnSelectedItem 事件 我想要做的是能够处理 ListBoxItem 的 OnMouseEnter 和
  • 如何将谷歌地图作为模板动态嵌入到另一个模板中

    谷歌地图通常显示为静态 html 但是我们需要在谷歌地图上动态显示数据 因此我们需要使用 javascript 将其作为模板嵌入到另一个模板中 它似乎是空白的 网页源代码显示调用了initialize 函数但地图没有出现 这是index h
  • 如何在iPhone SDK中将SQLite文件导出为CSV文件

    在我的应用程序中 我想将 SQLite 数据库文件导出到 CSV 文件 你能建议我如何做到这一点吗 谢谢 首先 您需要确保您正在使用FMDB访问数据库 因为在 Objective C 中直接使用 SQLite C API 的人都是受虐狂 你
  • WPF 用鼠标移动元素

    我正在尝试在 WPF 应用程序中用鼠标移动按钮 XAML Grid 是结构的根