Sometimes we do not have access to Window , for example. if we use DevExpress , all that is available is a UIElement .
Step 1: Add an Attached Property
Decision:
- Connect to
MouseMove events; - Search for the visual tree until we find the first parent of
Window ; - Call
.DragMove() on our newly opened Window .
the code:
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;
Step 2: add an attached property to any element so that it drags the window
The user can drag the whole window by clicking on a specific element if we add this attached property:
<Border local:EnableDragHelper.EnableDrag="True"> <TextBlock Text="Click me to drag this entire window"/> </Border>
Appendix A: Additional Advanced Example
In this example from DevExpress, we replace the dock window title bar with our own gray rectangle, and then make sure that if the user clicks and drags the specified gray rectangle, the window will usually be dragged:
<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>
Disclaimer: I am not an affiliate of DevExpress . This method will work with any user element, including standard WPF or Telerik (another excellent WPF library provider).
Contango Mar 11 '16 at 16:34 2016-03-11 16:34
source share