Manchmal haben wir keinen Zugriff auf Window
, z. B. wenn wir verwenden DevExpress
, ist nur a verfügbar UIElement
.
Schritt 1: Fügen Sie eine angehängte Eigenschaft hinzu
Die Lösung ist:
- Haken Sie in
MouseMove
Ereignisse ein;
- Durchsuchen Sie den visuellen Baum, bis wir den ersten Elternteil finden
Window
.
- Rufen Sie
.DragMove()
unseren neu entdeckten an Window
.
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;
// 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);
}
}
}
Schritt 2: Fügen Sie jedem Element eine angehängte Eigenschaft hinzu, damit es das Fenster ziehen kann
Der Benutzer kann das gesamte Fenster ziehen, indem er auf ein bestimmtes Element klickt, wenn wir diese angehängte Eigenschaft hinzufügen:
<Border local:EnableDragHelper.EnableDrag="True">
<TextBlock Text="Click me to drag this entire window"/>
</Border>
Anhang A: Optionales erweitertes Beispiel
In diesem Beispiel von DevExpress ersetzen wir die Titelleiste eines Docking-Fensters durch unser eigenes graues Rechteck und stellen dann sicher, dass das Fenster normal gezogen wird, wenn der Benutzer auf das graue Rechteck klickt und es zieht:
<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>
Haftungsausschluss: Ich bin nicht mit DevExpress verbunden . Diese Technik funktioniert mit jedem Benutzerelement, einschließlich Standard-WPF oder Telerik (einem anderen guten WPF-Bibliotheksanbieter).