问题描述
下面的是我从其它地方找到的WPF代码,可是自己不会WPF,还忘高人改成c#使用户能改变控件的位置,早已不是稀奇的事儿了。最近在WPF下实现了这一功能,并且尝试使用VisualBrush实现了拖动时的阴影效果。首先实例化一个Canvas布局:<Canvasx:Name="c"MouseDown="c_MouseDown"MouseMove="c_MouseMove"MouseUp="c_MouseUp"></Canvas>接着就是代码部分:注释在代码里面了publicpartialclassWindow1:Window{privatebooldragging;PointmousePoint;Rectangleshadow=newRectangle();//显示控件阴影的矩形ControlmouseCtrl=null;//被拖动的控件publicWindow1(){InitializeComponent();FullScreenManager.RepairWpfWindowFullScreenBehavior(this);dragging=false;shadow.Opacity=0.5;//阴影加点透明度c.Children.Add(shadow);//阴影加入canvasshadow.Visibility=Visibility.Hidden;//隐藏shadow}privatevoidc_MouseDown(objectsender,MouseButtonEventArgse){if(e.LeftButton==MouseButtonState.Pressed){dragging=true;//标记鼠标按下mousePoint=e.GetPosition(this.c);//获取鼠标在但前canvas内的位置mouseCtrl=(Control)e.Source;//获得事件触发的源,即哪个控件VisualBrushv;v=newVisualBrush(mouseCtrl);//利用VisualBrush得到控件的影像shadow.Width=mouseCtrl.Width;shadow.Height=mouseCtrl.Height;shadow.Fill=v;//将影像填充给矩形Canvas.SetLeft(shadow,Canvas.GetLeft(mouseCtrl));Canvas.SetTop(shadow,Canvas.GetTop(mouseCtrl));shadow.Visibility=Visibility.Visible;//使矩形可见//Canvas.SetZIndex(shadow,0);//可以通过SetZIndex设置阴影的z方向位置c.CaptureMouse();//强制捕获鼠标。这在对于背景透明的窗体里面是必须的}}privatevoidc_MouseMove(objectsender,MouseEventArgse){if(dragging){if(e.LeftButton==MouseButtonState.Pressed){PointtheMousePoint=e.GetPosition(this.c);Canvas.SetLeft(shadow,theMousePoint.X-(mousePoint.X-Canvas.GetLeft(shadow)));Canvas.SetTop(shadow,theMousePoint.Y-(mousePoint.Y-Canvas.GetTop(shadow)));//简单的计算,只移动shadowmousePoint=theMousePoint;}}}privatevoidc_MouseUp(objectsender,MouseButtonEventArgse){dragging=false;Mouse.Capture(null);//取消强制捕获shadow.Visibility=Visibility.Hidden;//隐藏shadowCanvas.SetLeft(mouseCtrl,Canvas.GetLeft(shadow));Canvas.SetTop(mouseCtrl,Canvas.GetTop(shadow));//将控件放到新的位置}}这里需要说明的是c.CaptureMouse();首先谈一下我的体会,刚开始没有写这句话,原因是在正常的窗体里面测试的。后来因为需要,将窗体背景设成透明后,发现shadow总是“跟不上”,仔细观察后发现,原因是当鼠标在透明的区域上划过的时候不会响应mousemove事件。所以如果窗体背景不是透明的话,写不写这句话都是一样的。后来在别人的提示下,强制捕获鼠标就解决了这个问题。并且尽管理论上这段代码具有通用性,也就是任何control下的元素都可以实现拖动。但是对于本身具有click或mousedown事件的元素,例如button,这段代码就不适用了。原因是mousedown事件在遇到这样的元素的时候还没来得及路由给canvas就被捕获了。在这个实例中还有一点,如果我们在代码里把一个控件实例化,并加到canvas里面后一定要手动设置它在canvas的位置Canvas.SetLeft(t,0);Canvas.SetTop(t,0);否则控件的位置是个“非数”。本文来自LesterDuo的博客,原文地
解决方案
解决方案二:
呵呵,你的想法很好如果不借用其他一些现成的类库是很难实现的。因为,在上面代码中出现的很多功能都,都是微软已经封住完毕的。上边的每一行代码,如果用其他的语言(结构框架)去实现,都可以能用几十行或上百行。
解决方案三:
这难道不是c#么?
解决方案四:
改成C#WINFORM的。