0

Border を持つ MainWindow と、Border のない Dialog として ChildWindow があります。子ウィンドウが開いているときは、メインウィンドウを移動したり、サイズを変更したりすることはできません。

アプリケーションが 1 つのウィンドウとして動作するようにしたい。

次のリンクのような動作を使用しようとしましたが、それは子ウィンドウをメインウィンドウ内に移動するだけです。

DragBahvior

4

3 に答える 3

3

ボーダレスWindowのドラッグまたは移動を有効にするはるかに簡単な方法があります。Window.DragMove詳細については、MSDN のメソッドページを参照してください。要するに、マウス ダウン イベント ハンドラーの 1 つのコードに次の行を追加するだけです。

public YourWindow()
{
    InitializeComponent();
    MouseLeftButtonDown += YourWindow_MouseLeftButtonDown;
}

...

private void YourWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DragMove(); // <-- this is all you need to add
}

その後、ユーザーは の任意の領域をクリックしてWindow(内部に何を配置したかによって異なります)、画面上でドラッグできます。

更新 >>>

ですから、私が最初に気づいた以上に、あなたの要件にはもっと多くのものがあるようです. あなたが望むものを達成するために、あなたがしなければならないことがたくさんあります。まず、に対してWindow特定の場所に子を配置する必要があります。開いたら、次のようにします。MainWindow.xaml Window

Window window = new Window();
window.Top = this.Top;
window.Left = this.Left;
window.LocationChanged += Window_LocationChanged;
window.ShowDialog();

子のWindow位置は、設定された量だけオフセットできます。

Window window = new Window();
window.Top = this.Top + someHorizontalOffsetAmount;
window.Left = this.Left + someVerticalOffsetAmount;
window.LocationChanged += Window_LocationChanged;
window.ShowDialog();

次に、イベントのハンドラーが必要ですWindow.LocationChanged(子Windowが移動したときに発生します)。

private void Window_LocationChanged(object sender, EventArgs e)
{
    Window window = (Window)sender;
    this.Top = window.Top;
    this.Left = window.Left;
}

それでおしまい!これで、2 つWindowの が一緒に移動します。明らかに、最初の例でオフセットを使用する場合は、Window_LocationChangedハンドラーで同じオフセットを使用する必要があります。

于 2014-05-20T10:10:22.193 に答える
1

ダイアログがModalのように聞こえます。つまり、呼び出されShowDialog()、メイン ウィンドウの移動を含め、閉じられるまでアプリケーションの残りの部分の使用を停止します。

これがあなたが望む動作ではない場合は、 を呼び出すだけでダイアログをモードレスShow()にする必要があります.ダイアログは完全に?

于 2014-05-20T10:29:06.033 に答える
0

だから私は最終的に解決策を見つけました。Windows クラスの拡張機能を書きましたが、非常に複雑でした :)

namespace MultiWindowWPF
{
  using System;
  using System.Drawing;
  using System.Linq;
  using System.Threading;
  using System.Windows;
  using System.Windows.Forms;
  using System.Windows.Input;
  using System.Windows.Media;
  using System.Windows.Threading;

  using Application = System.Windows.Application;

  public static class WindowExtensions
  {
    /// <summary>
    /// Shows the Dialog Modal.
    /// </summary>
    /// <param name="dialogWindow">The dialog window.</param>
    public static void ShowModal(this Window dialogWindow)
    {
      Window window = Application.Current.Windows.OfType<Window>().FirstOrDefault(w => w.IsKeyboardFocusWithin) ?? Application.Current.MainWindow;
      IInputElement lastFocused = FocusManager.GetFocusedElement(window);
      IInputElement lastKeyboardSelected = Keyboard.FocusedElement;
      EventHandler locationChanged = (sender, args) => ParentWndMove(dialogWindow);
      SizeChangedEventHandler sizeChanged = (sender, args) => ParentWndMove(dialogWindow);
      EventHandler stateChanged = (sender, args) => ParentWndStateChanged(dialogWindow);

      window.LocationChanged += locationChanged;
      window.SizeChanged += sizeChanged;
      window.StateChanged += stateChanged;

      EventHandler close = (sender, args) =>
      {

        if (dialogWindow.Dispatcher.CheckAccess())
        {
          dialogWindow.Close();
        }
        else
        {
          dialogWindow.Dispatcher.Invoke(dialogWindow.Close);
        }

        window.LocationChanged -= locationChanged;
        window.SizeChanged -= sizeChanged;
        window.StateChanged -= stateChanged;
      };

      EventHandler closed = (sender, args) =>
      {
        Window self = sender as Window;
        Enable();
        if (self != null)
        {
          self.Owner = null;
        }
      };

      ExitEventHandler exit = (sender, args) => close(sender, args);

      DependencyPropertyChangedEventHandler isEnabledChanged = null;
      isEnabledChanged = (o, eventArgs) =>
        {
          window.Dispatcher.BeginInvoke(
            DispatcherPriority.ApplicationIdle,
            new Action(
              () =>
                {
                  FocusManager.SetFocusedElement(window, lastFocused);
          Keyboard.Focus(lastKeyboardSelected);
        }));

        ((Window)o).IsEnabledChanged -= isEnabledChanged;
      };
      window.IsEnabledChanged += isEnabledChanged;
      dialogWindow.Closed += closed;
      Application.Current.Exit += exit;

      dialogWindow.Show();
      ParentWndMove(dialogWindow);

      while (Application.Current != null)
      {
        DoEvents();
      }
    }

    private static void DoEvents()
    {
      DispatcherFrame frame = new DispatcherFrame();
      Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame);
      Dispatcher.PushFrame(frame);
      Thread.Sleep(10);
    }

    private static void Enable()
    {
      foreach (Window window in Application.Current.Windows.OfType<Window>().Where(window => !window.OwnedWindows.OfType<Window>().Any()))
      {
        window.IsEnabled = true;
      }
    }

    /// <summary>
    /// Exits the frame.
    /// </summary>
    /// <param name="f">The f.</param>
    /// <returns></returns>
    public static object ExitFrame(object f)
    {
      ((DispatcherFrame)f).Continue = false;
      return null;
    }

    /// <summary>
    /// Parents the WND state changed.
    /// </summary>
    /// <param name="dialogWindow">The dialog window.</param>
    public static void ParentWndStateChanged(Window dialogWindow)
    {
      Window owner = dialogWindow.Owner;
      if (owner.WindowState != WindowState.Maximized)
      {
        dialogWindow.WindowState = owner.WindowState;
      }
      ParentWndMove(dialogWindow);
    }

    /// <summary>
    /// Parents the WND move.
    /// </summary>
    /// <param name="dialogWindow">The dialog window.</param>
    public static void ParentWndMove(Window dialogWindow)
    {
      Window owner = dialogWindow.Owner;
      PresentationSource presentationsource = PresentationSource.FromVisual(dialogWindow);
      Matrix m = presentationsource.CompositionTarget.TransformToDevice;

      double centerWidth = owner.Left + owner.ActualWidth / 2;
      double centerHeight = owner.Top + owner.ActualHeight / 2;
      if (owner.WindowState == WindowState.Normal)
      {
        dialogWindow.Top = centerHeight - dialogWindow.ActualHeight / 2;
        dialogWindow.Left = centerWidth - dialogWindow.ActualWidth / 2;
      }
      if (owner.WindowState == WindowState.Maximized)
      {
        //there is no current main window position to use, center on working screen
        Rectangle frame = Screen.FromPoint(new System.Drawing.Point((int)(dialogWindow.Left * m.M11), (int)(dialogWindow.Top * m.M22))).Bounds;

        dialogWindow.Left = frame.X / m.M11 + (frame.Width / m.M11 - dialogWindow.ActualWidth) / 2;
        dialogWindow.Top = frame.Y / m.M22 + (frame.Height / m.M22 - dialogWindow.ActualHeight) / 2;
      }
    }
  }
}
于 2014-05-20T13:01:36.210 に答える