0

好的,由于缺乏回复,所以完全重写了问题。我想要一个可拖动的窗口,但在拖动时,更改边距以延伸到窗口的旧位置。即窗口向右移动 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
        }

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

旧 - 仅阅读以了解我正在尝试做什么

因此,我正在尝试创建一个具有弹出窗口的应用程序,该窗口带有从子窗口指向父窗口中特定位置的指针/线。我是这样实现的;

<Border Name="brdr" Margin="40,0,0,0" >
    //Content
</Border>

<Line
        Name="Pointer"
        X1="0"
        X2="40"
        Y1="55"
        Y2="50"
        StrokeThickness="2"
        Stroke="Black"
></Line>

请注意边框上的 40 左侧Margin使窗口比它看起来更大,因此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坐标重置为新值。正如我所说,所有这些值都是通过将打开窗口坐标与当前坐标进行比较来计算的。

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

4

3 回答 3

0

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

    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));

如果我不这样做,则会出现放置错误,越向右错误越多。

于 2012-07-04T14:33:56.997 回答
0

实际上找到了这样做的好方法。我所做的是我设置了子窗口,WindowState="Maximized"然后将除 a 之外的所有内容都放置Line在 a 中Canvas,然后按照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 = p.X;
Line.Y2 = p.Y + 50;

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

于 2012-07-05T07:51:37.520 回答
0

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

<Grid>
    <Line x:Name="MyLine"  Stroke="Black" StrokeThickness="4" />
    <Button Name="MyButton"                Margin="248,101,0,0"
            HorizontalAlignment="Left"   VerticalAlignment="Top"
            Content="Button" />
</Grid>

然后我做了另一个名为TestWindow的小尺寸(300 * 300)窗口。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。但是这个想法是有一个透明的弹出窗口,它覆盖了你做同样事情的整个屏幕。

于 2012-07-04T15:35:36.313 回答