首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无论单击哪个元素,都使WPF窗口可拖动

无论单击哪个元素,都使WPF窗口可拖动
EN

Stack Overflow用户
提问于 2011-09-14 22:09:54
回答 10查看 100K关注 0票数 127

我的问题是2折,我希望有更简单的解决方案,由WPF提供,而不是来自WinForms的标准解决方案( Christophe Geers提供,在我做出这一澄清之前)。

首先,有没有一种方法可以在不捕获和处理鼠标单击+拖动事件的情况下使窗口可拖动?我的意思是窗口可以通过标题栏拖动,但是如果我设置了一个窗口没有标题栏,但仍然想要拖动它,有没有一种方法可以将事件以某种方式重定向到处理标题栏拖动的东西?

其次,有没有一种方法可以将事件处理程序应用于窗口中的所有元素?与中一样,无论用户click+drags是哪个元素,都要使窗口可拖动。显然不需要手动添加处理程序到每个元素。就在某个地方做一次?

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2011-09-14 23:08:01

当然,应用Window的以下MouseDown事件

代码语言:javascript
复制
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.ChangedButton == MouseButton.Left)
        this.DragMove();
}

这将允许用户在单击/拖动任何控件时拖动窗口,但处理MouseDown事件(e.Handled = true)的控件除外

您可以使用PreviewMouseDown而不是MouseDown,但拖动事件会占用Click事件,因此窗口将停止响应鼠标左键单击事件。如果您确实希望能够从任何控件中单击并拖动窗体,则可以使用PreviewMouseDown,启动计时器开始拖动操作,如果MouseUp事件在X毫秒内触发,则取消操作。

票数 315
EN

Stack Overflow用户

发布于 2013-11-30 21:07:49

如果wpf窗体需要是可拖动的,无论它是在哪里单击的,那么简单的变通方法是使用委托在windows onload事件或网格加载事件上触发DragMove()方法

代码语言:javascript
复制
private void Grid_Loaded(object sender, RoutedEventArgs 
{
      this.MouseDown += delegate{DragMove();};
}
票数 10
EN

Stack Overflow用户

发布于 2016-03-12 00:34:36

有时,我们无法访问Window,例如,如果我们使用DevExpress,则所有可用的都是UIElement

第1步:添加附加属性

解决方案是:

  1. 挂钩到MouseMove events;
  2. 向上搜索可视化树,直到我们在新发现的Window.

上找到第一个父Window;

  • Call .DragMove()

代码:

代码语言:javascript
复制
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace DXApplication1.AttachedProperty
{
    public class EnableDragHelper
    {
        public static readonly DependencyProperty EnableDragProperty = DependencyProperty.RegisterAttached(
            "EnableDrag",
            typeof (bool),
            typeof (EnableDragHelper),
            new PropertyMetadata(default(bool), OnLoaded));

        private static void OnLoaded(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var uiElement = dependencyObject as UIElement;
            if (uiElement == null || (dependencyPropertyChangedEventArgs.NewValue is bool) == false)
            {
                return;
            }
            if ((bool)dependencyPropertyChangedEventArgs.NewValue  == true)
            {
                uiElement.MouseMove += UIElementOnMouseMove;
            }
            else
            {
                uiElement.MouseMove -= UIElementOnMouseMove;
            }

        }

        private static void UIElementOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
        {
            var uiElement = sender as UIElement;
            if (uiElement != null)
            {
                if (mouseEventArgs.LeftButton == MouseButtonState.Pressed)
                {
                    DependencyObject parent = uiElement;
                    int avoidInfiniteLoop = 0;
                    // Search up the visual tree to find the first parent window.
                    while ((parent is Window) == false)
                    {
                        parent = VisualTreeHelper.GetParent(parent);
                        avoidInfiniteLoop++;
                        if (avoidInfiniteLoop == 1000)
                        {
                            // Something is wrong - we could not find the parent window.
                            return;
                        }
                    }
                    var window = parent as Window;
                    window.DragMove();
                }
            }
        }

        public static void SetEnableDrag(DependencyObject element, bool value)
        {
            element.SetValue(EnableDragProperty, value);
        }

        public static bool GetEnableDrag(DependencyObject element)
        {
            return (bool)element.GetValue(EnableDragProperty);
        }
    }
}

步骤2:将附加属性添加到任何元素,以允许其拖动窗口

如果我们添加以下附加属性,用户可以通过单击特定元素来拖动整个窗口:

代码语言:javascript
复制
<Border local:EnableDragHelper.EnableDrag="True">
    <TextBlock Text="Click me to drag this entire window"/>
</Border>

附录A:可选的高级示例

在这个来自DevExpress的例子中,我们用我们自己的灰色矩形替换了停靠窗口的标题栏,然后确保如果用户点击并拖动灰色矩形,窗口将正常拖动:

代码语言:javascript
复制
<dx:DXWindow x:Class="DXApplication1.MainWindow" Title="MainWindow" Height="464" Width="765" 
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking" 
    xmlns:local="clr-namespace:DXApplication1.AttachedProperty"
    xmlns:dxdove="http://schemas.devexpress.com/winfx/2008/xaml/docking/visualelements"
    xmlns:themeKeys="http://schemas.devexpress.com/winfx/2008/xaml/docking/themekeys">

    <dxdo:DockLayoutManager FloatingMode="Desktop">
        <dxdo:DockLayoutManager.FloatGroups>
            <dxdo:FloatGroup FloatLocation="0, 0" FloatSize="179,204" MaxHeight="300" MaxWidth="400" 
                             local:TopmostFloatingGroupHelper.IsTopmostFloatingGroup="True"                             
                             >
                <dxdo:LayoutPanel ShowBorder="True" ShowMaximizeButton="False" ShowCaption="False" ShowCaptionImage="True" 
                                  ShowControlBox="True" ShowExpandButton="True" ShowInDocumentSelector="True" Caption="TradePad General" 
                                  AllowDock="False" AllowHide="False" AllowDrag="True" AllowClose="False"
                                  >
                    <Grid Margin="0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Border Grid.Row="0" MinHeight="15" Background="#FF515151" Margin="0 0 0 0"
                                                                  local:EnableDragHelper.EnableDrag="True">
                            <TextBlock Margin="4" Text="General" FontWeight="Bold"/>
                        </Border>
                        <TextBlock Margin="5" Grid.Row="1" Text="Hello, world!" />
                    </Grid>
                </dxdo:LayoutPanel>
            </dxdo:FloatGroup>
        </dxdo:DockLayoutManager.FloatGroups>
    </dxdo:DockLayoutManager>
</dx:DXWindow>

免责声明:我与DevExpress没有关联。这项技术适用于任何用户元素,包括standard WPFTelerik (另一个优秀的WPF库提供商)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7417739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档