C# WPF PRISM - 让用户控件可拖动

4

如果默认的棱镜对话框有可拖动选项,那确实会很棒。 - Haukinger
如果你想让用户可以拖动它,为什么不把它做成一个窗口呢? - Andy
虽然可以使UserControl变成可拖动的(而且也很容易),但这会带来一个很大的限制。父窗口不允许在客户区之外呈现内容。这意味着当用户试图将您的UserControl拖出客户区时,它将被裁剪。我认为这使得UserControl无法作为可拖动对话框。如果对话框是模态的,您可以考虑将其制成固定对话框。用户可以通过拖动应用程序窗口来拖动它。否则,请使用Window或Popup替换UserControl(就像Andy建议的那样)。 - BionicCode
1个回答

3

我不确定是否理解正确,但您想要一种行为,即当用户控件被拖动时,希望父窗口也被拖动。因此,这里是实现:

public class DragParentWindowBehavior : Behavior<UserControl>
    {
        private Window parentWindow;

        protected override void OnAttached()
        {
            AssociatedObject.Loaded += AssociatedObject_Loaded;
            AssociatedObject.Unloaded += AssociatedObject_Unloaded;
            AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
        }

        private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
        {
            parentWindow = null;
        }

        private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
           //We get the parent window here. because the behavior is attached to the view way before it is shown.
            parentWindow = Window.GetWindow(AssociatedObject);
        }

        private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            parentWindow?.DragMove();
        }

        protected override void OnDetaching()
        {
            AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
            AssociatedObject.Loaded -= AssociatedObject_Loaded;
            AssociatedObject.Unloaded -= AssociatedObject_Unloaded;

            parentWindow = null;
        }
    }

这是在XAML中使用它的方法:

<UserControl x:Class="Prism1.Modules.ModuleName.Views.DraggableControl"
             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:Prism1.Modules.ModuleName.Views" 
             xmlns:Behaviors="http://schemas.microsoft.com/xaml/behaviors" 
             xmlns:mvvm="clr-namespace:Prism1.Core.Mvvm;assembly=Prism1.Core"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Behaviors:Interaction.Behaviors>
        <mvvm:DragParentWindowBehavior></mvvm:DragParentWindowBehavior>
    </Behaviors:Interaction.Behaviors>
    <Grid x:Name="LayoutRoot" Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TextBlock Text="{Binding Message}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" TextWrapping="Wrap" />
        <Button Command="{Binding CloseDialogCommand}" CommandParameter="true" Content="OK" Width="75" Height="25" HorizontalAlignment="Right" Margin="0,10,0,0" Grid.Row="1" IsDefault="True" />
    </Grid>
</UserControl>

1
它运行得很好,谢谢!只有一个小问题需要改变。用户无法访问控件,因此您必须将AssociatedObject.PreviewMouseLeftButtonDown替换为AssociatedObject.MouseLeftButtonDown。 - MaxB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接