窗口拖动的动态余量

好的,由于缺乏回复,完全重写了问题。 我想要一个可拖动的窗口,但是当它被拖动时,改变边距以延伸到窗口的旧位置。 即窗口向右移动X,向左延伸边缘X.现在我已经遇到了一些障碍,例如窗口由于某种原因切断了边缘。 这是我的代码,让我知道你是否能发现任何东西!

private void Window_LocationChanged(object sender, EventArgs e) { double TmpLeft = Math.Abs(this.Left - WinLeft); double TmpTop = Math.Abs(this.Top - WinTop); if (this.IsLoaded) {//depending on whether the window is moved left, right if (this.Left > WinLeft) {//depending on whether the window is moved up, down if (this.Top > WinTop) bdr.Margin = new Thickness(TmpLeft, TmpTop, 0, 0); else bdr.Margin = new Thickness(TmpLeft, 0, 0, TmpTop); } else { if (this.Top > WinTop) bdr.Margin = new Thickness(0, TmpTop, TmpLeft+ 40, 0); else bdr.Margin = new Thickness(0, 0, TmpLeft, TmpTop); } } } private void Window_Loaded(object sender, RoutedEventArgs e) { WinLeft = this.Left; WinTop = this.Top; bdr.Height = this.ActualHeight;//I set these because they are auto bdr.Width = this.ActualWidth; //before the window opens } 

此时整个窗口(将窗口背景设置为黄色以便我可以看到边距)正在移动,我希望边缘的左上角保持在原位。 我还注意到,我点击拖动窗口( border )的区域也会移动,所以当我移动窗口时,不再是我的点击。 希望清楚,评论任何进一步的问题。

老 – 只读了解我在做什么

所以我正在尝试创建一个应用程序,它有一个弹出窗口,指针/行从子窗口到父窗口中的特定位置。 我这样做了;

  //Content   

注意边框上的40左边距使窗口比显示的大,这样Polygon向左伸出并指向父窗口(如果有更好/更酷/更优雅的方式这样做,我都是耳朵)。

所以这很好但现在我希望指针是动态的。 如在,如果拖动子窗口,指针必须相对于父窗口的位置缩放。 即它必须看起来好像两个窗口通过线路连接。 现在我的计划是记录子窗口打开的点(因为它相对于父窗口打开,初始化时它是正确的)然后使用它与新位置点之间的差异(拖动后)来查找新点这条线应该去。 我的代码可能说它比我更好……

  private void Window_LocationChanged(object sender, EventArgs e) { if (this.IsLoaded) { brdr.Margin = new Thickness(Math.Abs(this.Left - WinLeft) + 40, Math.Abs(this.Top - WinTop), 0, 0); Pointer.X1 = Math.Abs(this.Left - WinLeft); Pointer.Y1 = Math.Abs(this.Top - WinTop) + 55; Pointer.X2 = Math.Abs(this.Left - WinLeft) + 40; Pointer.Y2 = Math.Abs(this.Top - WinTop) + 50; } } private void Window_Loaded(object sender, RoutedEventArgs e) { WinLeft = this.Left; WinTop = this.Top; } 

如你所见,我必须设置窗口边距,使其延伸到旧位置。 然后我将Line coords重置为新值。 正如我所说,所有这些值都通过比较开口窗口坐标与当前坐标而计算出来。

我的问题是,这是不对的。 看到有人能够解决这个问题会非常深刻。

我很惊讶没有代码可以从窗口内坐标切换到屏幕坐标。 在我的一个项目中,我不得不在控制下放置一个窗口。 我用它来获取控件中间点的屏幕坐标:

  Point point = MyControl.PointToScreen(new Point((MyControl.ActualWidth / 2) , MyControl.ActualHeight)); PresentationSource source = PresentationSource.FromVisual(MyControl); double dpiX = (96 * source.CompositionTarget.TransformToDevice.M11); double dpiY = (96 * source.CompositionTarget.TransformToDevice.M22); XInScreenCoordinates = ((point.X * 96 / dpiX)); YInScreenCoordinates = ((point.Y * 96 / dpiY)); 

如果我没有这样做,放置时会出错,右边越多,错误越多。

好吧,我做了一个小应用程序:
还有MainWindow,内容非常简单的主窗口,一行和一个Button:

     

然后我做了另一个窗口,小尺寸(300 * 300)名为TestWindow。 TestWindow没有任何内容或代码。

MainWindow背后的代码:

 public partial class MainWindow : Window { public TestWindow MyTestWindow; public MainWindow() { InitializeComponent(); MyTestWindow = new TestWindow(); MyTestWindow.Show(); MyTestWindow.LocationChanged += new EventHandler(WinLocationChanged); MyTestWindow.SizeChanged += new SizeChangedEventHandler ( WinSizeChanged); this.LocationChanged += new EventHandler(WinLocationChanged); this.SizeChanged += new SizeChangedEventHandler(WinSizeChanged); } void WinSizeChanged(object sender, SizeChangedEventArgs e) { UpdateLine(); } void WinLocationChanged(object sender, EventArgs e) { UpdateLine(); } void UpdateLine() { // 1. get Window's center in in this window coordinates double CX_sc =0.0, CY_sc = 0.0; GetWindowCoordinatesInCurrentWindow(MyTestWindow, ref CX_sc, ref CY_sc); // 2. Get Center of target Control coordinates in this window coordinates Point CenterButtonPoint = MyButton.TransformToAncestor(this).Transform(new Point(MyButton.ActualWidth / 2.0, MyButton.ActualHeight / 2.0)); //3. Change line's coord. MyLine.X1 = CX_sc; MyLine.Y1 = CY_sc; MyLine.X2 = CenterButtonPoint.X; MyLine.Y2 = CenterButtonPoint.Y; } void GetWindowCoordinatesInCurrentWindow(Window ChildWindow, ref double X, ref double Y) { Point CenterOfChildWindow = ChildWindow.PointToScreen(new Point((ChildWindow.ActualWidth / 2) , ChildWindow.ActualHeight/2)); Point UpperLeftOfCurrentWindow = this.PointToScreen(new Point(0, 0)); PresentationSource source = PresentationSource.FromVisual(this); double dpiX = ( source.CompositionTarget.TransformToDevice.M11); double dpiY = (source.CompositionTarget.TransformToDevice.M22); X = (( CenterOfChildWindow.X -UpperLeftOfCurrentWindow.X ) /dpiX); Y = ( (CenterOfChildWindow.Y-UpperLeftOfCurrentWindow.Y ) / dpiY ); } } 

它的作用是,无论何时移动一个窗口或调整其大小,它都会在MainWindow中绘制一条线,将Button“链接”到TestWindow的中间。

好的我知道这不是你想要的:=),因为该行不能超出MainWindow。 但我们的想法是拥有一个透明的Popup,它覆盖整个屏幕,你可以在其中做同样的事情。

实际上找到了一个很好的方法。 我所做的是设置子窗口的WindowState="Maximized"然后在Canvas放置除Line之外的所有内容,并遵循http://denismorozov.blogspot.ie/2008/01/drag-controls-in-wpf-using。 HTML (伟大的文章)我可以做到这一点,我可以在我的窗口移动。 我对该线进行了硬编码,以便在窗口打开时它处于正确的位置。 由于Line其中一个点不应移动,因此只需更新Canvas_MouseMove事件中的另一个点就可以了;

 Point p = border.TransformToAncestor(this).Transform(new Point(0, 0)); Line.X2 = pX; Line.Y2 = pY + 50; 

如果你想要一条连接两者的线,让你的窗口相对于父窗口显示的非常简单的方法。 它给出了移动窗口的外观,但实际上是围绕最大化的透明窗口移动控件。