如何阻止移动的用户控件与其他相同类型的用户控件相交?

时间:2018-12-09 18:49:59

标签: c# wpf xaml user-controls geometry

您好:)我正在WPF中工作,我的主窗口是画布。我创建了一个名为 Country 的用户控件,可以使用鼠标沿主窗口移动它:

public partial class Country : UserControl
{
    private Point position = new Point(0, 0);
    private Point mousePosition = new Point(0, 0);
    protected Boolean isDragging;
    private Double prevX, prevY;
    public static List<Country> list = new List<Country>();
    public static int num = 1;
    private string riddle;

    public Country()
    {
        InitializeComponent();
        this.Height = 100;
        this.Width = 100;
        this.Background = Brushes.Red;
        this.Content = "country" + num;
        num++;
        position = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
        this.MouseLeftButtonDown += new MouseButtonEventHandler(Control_MouseLeftButtonDown);
        this.MouseLeftButtonUp += new MouseButtonEventHandler(Control_MouseLeftButtonUp);
        this.MouseMove += new MouseEventHandler(Control_MouseMove);
        list.Add(this);
    }

    private void Control_MouseLeftButtonDown(Object sender, MouseButtonEventArgs e)
    {
        isDragging = true;
        var draggableControl = (sender as UserControl);
        mousePosition = e.GetPosition(Parent as UIElement);
        draggableControl.CaptureMouse();
    }

    private void Control_MouseLeftButtonUp(Object sender, MouseButtonEventArgs e)
    {
        isDragging = false;
        var draggable = (sender as UserControl);
        var transform = (draggable.RenderTransform as TranslateTransform);
        if (transform != null)
        {
            prevX = transform.X;
            prevY = transform.Y;
        }
        draggable.ReleaseMouseCapture();
    }

    private void Control_MouseMove(Object sender, MouseEventArgs e)
    {
                var draggableControl = (sender as UserControl);
                if (isDragging && draggableControl != null)
                {
                    var currentPosition = e.GetPosition(Parent as UIElement);
                    var transform = (draggableControl.RenderTransform as TranslateTransform);
                    if (transform == null)
                    {
                        transform = new TranslateTransform();
                        draggableControl.RenderTransform = transform;
                    }
                    double aX = transform.X;
                    double aY = transform.Y;
                    transform.X = (currentPosition.X - mousePosition.X);
                    transform.Y = (currentPosition.Y - mousePosition.Y);
                    if (prevX > 0)
                    {
                        transform.X += prevX;
                        transform.Y += prevY;
                    }
                }
            }
        }

这是xaml代码:

<UserControl x:Class="WpfApplication7.Country"
         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:WpfApplication7"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Width="100" Height="100" Background="Red">

</Grid>
</UserControl>

我一直在尝试防止 Country 的实例彼此相交,也就是说-如果我在MainWindow中有多个国家,并且我正在移动一个国家并且即将相交如果您与另一个国家/地区在一起,则移动的国家/地区会停止或返回,或者类似的事情。 不幸的是,我想到的所有想法都失败了。我应该在MainWindow中做些什么吗?如果有人可以提供解决方案或真知灼见,我将非常高兴。

我们将不胜感激

2 个答案:

答案 0 :(得分:0)

从用户的经验出发,更好的解决方案不是停止下药,而只是向用户指示该操作无法执行。我建议您进行一些更改,例如更改光标(例如在标准Windows拖放应用程序中)或更改处于下注状态的对象(在某些游戏中使用此方法)或两者的颜色。

我认为,您应该在Country类中有一个事件,并在主窗口中有一个适当的事件处理程序。因此,您可以跟踪任何国家的动向并轻松做出反应。

答案 1 :(得分:0)

将公共rect变量添加到国家/地区。 当您将它们添加到画布时,添加到主窗口中的列表。 处理画布上的previewmousemove等以移动它们。 拖动时,使用当前的顶部和左侧,实际的高度和宽度更新矩形。 遍历您的国家/地区列表。 使用rect.intersectsWith查看它们在新位置是否重叠。 如果这样,则停止拖动并且不要移动控件。

相关问题