使文本移动,矩形位于顶部

时间:2012-12-20 15:12:46

标签: c# 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()中称为blockname。我已经尝试过Binding,你可以在这里看到,但我认为我对更容易实现这一目标的知识存在差距。无论哪种方式,当触发鼠标事件处理程序时,我希望文本在块下移动时移动。如何让文本随之移动?

1 个答案:

答案 0 :(得分:1)

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

btw我建议将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
}