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>

Marginウィンドウが表示よりも大きくなるように境界線に残っている40に注意してください。これにより、Polygonスティックが左に突き出て、親ウィンドウを指します(これを行うためのより良い/より涼しい/よりエレガントな方法がある場合、私はすべての耳です) 。

これで問題なく動作しましたが、ポインタを動的にする必要があります。のように、子ウィンドウがドラッグされた場合、ポインタは親ウィンドウの位置に対して相対的に拡大縮小する必要があります。つまり、2つのウィンドウが線で接続されているように見える必要があります。今、私の計画は、子ウィンドウが開くポイントを記録し(親ウィンドウに対して開くため、初期化すると正しい)、これと新しい場所のポイント(ドラッグ後)の差を使用して新しいポイントを見つけることでした。その行が行くべきです。私のコードはおそらく私がこれまでにできたよりも良いと言っています...

    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

私がやった小さなアプリです:
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 );
    }


}

ウィンドウの1つを移動またはサイズ変更すると、メインウィンドウに線が引かれ、ボタンがテストウィンドウの中央に「リンク」されます。

OK OKこれはあなたが望むものではないことを私は知っています:=)、行はMainWindowの外に出ることができないからです。しかし、アイデアは、同じことを行う画面全体をカバーする透明なポップアップを作成することです。

于 2012-07-04T15:35:36.313 に答える
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"を除くすべてをLineaに配置し、 http://denismorozov.blogspot.ie/2008/01/drag-controls-in-wpf-using.html(すばらしい記事)にCanvas従うことでできました。窓の周りを移動できるようにします。ウィンドウが開いたときに正しい位置になるように、行をハードコーディングしました。のポイントの1つは移動してはならないので、そのようなイベントで他のポイントを更新するだけでした。LineCanvas_MouseMove

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

2つを結ぶ線が必要な場合は、親ウィンドウを基準にしてウィンドウを表示する非常に簡単な方法。ウィンドウを動かしているように見えますが、実際には、最大化された透明なウィンドウの周りでコントロールを動かしています。

于 2012-07-05T07:51:37.520 に答える