1

我是silverlight的新手,所以我可能只是因为缺乏知识而遗漏了一些东西。我正在编写一个使用矩形的应用程序,您可以在它们生成后单击并拖动到屏幕周围。我有生成矩形的函数:

    public void formatBox(block b)
    {
        Rectangle Rec = new Rectangle();
        Rec.Height = 100;
        Rec.Width = 200;
        SolidColorBrush newBrush = new SolidColorBrush();
        newBrush.Color = b.blockColor;
        SolidColorBrush blackBrush = new SolidColorBrush();
        blackBrush.Color = Colors.Black;
        Rec.StrokeThickness = 4;
        Rec.Stroke = blackBrush;
        Rec.Fill = newBrush;
        Canvas.SetTop(Rec, generateY(b.locationY));
        Canvas.SetLeft(Rec, generateX(b.locationX));
        TextBlock blockname = new TextBlock();
        blockname.Text = b.blockText;
        blockname.FontSize = 25;
        canvas1.Children.Add(Rec);
        canvas1.Children.Add(blockname);
        Binding topbinding = new Binding("Top");
        Binding leftbinding = new Binding("Left");
        topbinding.Mode = BindingMode.OneWay;
        leftbinding.Mode = BindingMode.OneWay;
        topbinding.Source = Rec.GetValue(Canvas.TopProperty);
        leftbinding.Source = Rec.GetValue(Canvas.LeftProperty);
        blockname.SetBinding(Canvas.TopProperty, topbinding);
        blockname.SetBinding(Canvas.LeftProperty, leftbinding);
        Rec.MouseLeftButtonDown += new MouseButtonEventHandler(Handle_MouseDown);
        Rec.MouseMove += new MouseEventHandler(Handle_MouseMove);
        Rec.MouseLeftButtonUp += new MouseButtonEventHandler(Handle_MouseUp);
    }

这些矩形是从一个块类构建的

public class block
    {
        public double locationX { get; set; }
        public double locationY { get; set; }
        public Color blockColor { get; set; }
        public string blockText { get; set; }
        public block(double x, double y, Color c, string s)
        {
            this.locationX = x;
            this.locationY = y;
            this.blockColor = c;
            this.blockText = s;
        }
    }

还有我的鼠标事件处理程序:

    bool isMouseCaptured;
    double mouseVerticalPosition;
    double mouseHorizontalPosition;

    public void Handle_MouseDown(object sender, MouseEventArgs args)
    {
        Rectangle item = sender as Rectangle;
        mouseVerticalPosition = args.GetPosition(null).Y;
        mouseHorizontalPosition = args.GetPosition(null).X;
        isMouseCaptured = true;
        item.CaptureMouse();
    }

    public void Handle_MouseMove(object sender, MouseEventArgs args)
    {
        Rectangle item = sender as Rectangle;
        if (isMouseCaptured)
        {

            // Calculate the current position of the object.
            double deltaV = args.GetPosition(null).Y - mouseVerticalPosition;
            double deltaH = args.GetPosition(null).X - mouseHorizontalPosition;
            double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
            double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

            // Set new position of object.
            item.SetValue(Canvas.TopProperty, newTop);
            item.SetValue(Canvas.LeftProperty, newLeft);

            // Update position global variables.
            mouseVerticalPosition = args.GetPosition(null).Y;
            mouseHorizontalPosition = args.GetPosition(null).X;
        }
    }


    public void Handle_MouseUp(object sender, MouseEventArgs args)
    {
        Rectangle item = sender as Rectangle;
        isMouseCaptured = false;
        item.ReleaseMouseCapture();
        mouseVerticalPosition = -1;
        mouseHorizontalPosition = -1;
    }

我试图移动的文本在 formatBox() 中称为块名。正如您在此处看到的那样,我已经尝试过 Binding,但我认为我对更简单的方法的了解存在差距。无论哪种方式,当触发鼠标事件处理程序时,我希望文本在块移动时移动。如何让文本随它移动?

4

1 回答 1

1

由于您已经有了鼠标处理程序,您可以跳过绑定并使用代码。(无论如何,绑定都不会按预期工作:文本将具有与反应角相同的坐标,因此它被绘制在矩形的顶部/左侧线上。这看起来很难看并且使文本难以阅读,您需要偏移文本,使其位于反应角内部或外部)。基本上你要做的就是MouseDown将一个标志置于高位以指示鼠标被按下,并记录鼠标所在的点。然后在MouseMove你检查标志:如果它打开,计算你的矩形的新位置,因为它是当前位置+从记录的点移动的距离MouseDown。文本的位置将是新位置 + 一些偏移量。

顺便说一句,我建议将诸如 formatBox 之类的方法拆分为多个较小的方法,并为变量选择更好的名称:这将使代码不仅更具可读性,而且更易于维护。

编辑 以确定要移动的矩形,对 MouseDwon 处理程序中的所有元素进行命中测试。像这样的东西:

Rectangle rectangleUnderMouse = null;
foreach( var rec in rectangles )
{
  if( VisualTreeHelper.HitTest( rec, pointWhereMouseIs ) )
  {
    rectangleUnderMouse = rec;
    break;
  }
}

编辑 抱歉,我没有看到您询问要移动哪个文本块。这更容易:您可以Dictionary<Rectangle,TextBlock>在主类中保留一个:

public void formatBox(block b)
{
  //...
  myDictionary[ Rec ] = textblock;
}

public void Handle_MouseMove( object sender, MouseEventArgs args ) 
{
  //...
  textBlockForThisRect = myDictionary[ item ];
  //move textBlockForThisRect
}
于 2012-12-20T15:42:20.457 回答