web-dev-qa-db-ja.com

(システム全体ではなく)アプリの他のすべてのウィンドウの上にWPFウィンドウを作成する方法は?

私のウィンドウを他のすべてのウィンドウの上に配置したい私のアプリケーションのみ。ウィンドウのTopMostプロパティを設定すると、すべてのアプリケーションのすべてのウィンドウの一番上になり、それは望ましくありません。

56
Sylvain

ウィンドウの所有者プロパティを設定する必要があります。

メインウィンドウをブロックするには、showdialogを使用してウィンドウを表示するか、通常のウィンドウを表示して、所有者をブロックせずに所有者の上に表示します。

分離コード部分のコード例を次に示します-明らかなものはすべて省きました。

namespace StackoverflowExample
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }
    void NewWindowAsDialog(object sender, RoutedEventArgs e)
    {
      Window myOwnedDialog = new Window();
      myOwnedDialog.Owner = this;
      myOwnedDialog.ShowDialog();
    }
    void NormalNewWindow(object sender, RoutedEventArgs e)
    {
      Window myOwnedWindow = new Window();
      myOwnedWindow.Owner = this;
      myOwnedWindow.Show();
    }
  }
}
39
Johannes

代わりに、常にTopMostであるPopupを使用し、Windowと同様に装飾し、メインWindowのLocationChangedイベントを処理するアプリケーションに完全にアタッチし、PopupのIsOpenプロパティをfalseに設定します。

編集:

このようなものが欲しいと願っています:

    Window1 window;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        window = new Window1();
        window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
        window.Topmost = true;
        this.LocationChanged+=OnLocationchanged;
        window.Show();
    }

    private void OnLocationchanged(object sender, EventArgs e)
    {
          if(window!=null)
              window.Close();
    }

それが役に立てば幸い!!!

15
viky
CustomWindow cw = new CustomWindow();

cw.Owner = Application.Current.MainWindow;

cw.ShowInTaskbar = false;

cw.ShowDialog() ; 
11
Alex

[〜#〜] xaml [〜#〜]で簡単に実行でき、この回答がまだ誰も投稿していないことに驚いた。次の例では、WindowResourceLibraryで定義されています(x:Key)。ただし、スタンドアロンのPage- style WPFリソースでこのXAMLバインディングを使用することもできます。

<Window x:Key="other_window" 
        Topmost="{Binding Source={x:Static Application.Current},Path=MainWindow.IsActive,Mode=OneWay}">
    <TextBlock Text="OTHER WINDOW" />
</Window>
6
Glenn Slayden

最良の方法は、この2つのイベントをアプリのすべてのウィンドウに設定することです。

GotKeyboardFocus
LostKeyboardFocus

この方法では:

WiondowOfMyApp_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = true;
}

WiondowOfMyApp_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
{
    windowThatShouldBeTopMost.TopMost = false;
}
  • そして、トップになりたいすべてのウィンドウは、アプリの他のウィンドウからアクセスできるはずです。私の場合、ベースウィンドウと、ベースウィンドウの最上部にある別のウィンドウがあるため、ベースウィンドウがお互いのウィンドウのインスタンスを持っていることは悪くありませんでした。
5
Omid-RH

activate()メソッドを使用します。これにより、ウィンドウが前面に表示され、アクティブになります。例えばウィンドウwnd = new xyz(); wnd.Activate();

5
Sudhakar Singh

私はあなたと非常によく似た状況に遭遇しました。 searches のほとんどは、トップウィンドウにしたいウィンドウの所有者をメインウィンドウまたはShowと呼ばれるウィンドウに設定するだけでよいと述べました。

とにかく、私は先に進み、私のためにうまくいった解決策を投稿します。

アプリケーションに関してTopmostになるはずのウィンドウにWindow.ActivatedおよびWindow.Deactivedのイベントハンドラーを作成しました。

private void Window_Activated(object sender, EventArgs e)
{
    Topmost = true;
}

private void Window_Deactived(object sender, EventArgs e)
{
    if(Owner == null || Owner.IsActive)
        return;
    bool hasActiveWindow = false;
    foreach(Window ownedWindow in Owner.OwnedWindows)
    {
        if(ownedWindow.IsActive)
            hasActiveWindow = true; 
    }

    if(!hasActiveWindow)
        Topmost = false;
}

それは私にとって素晴らしい作品です。うまくいけば、これは他の誰かに役立つでしょう。 :o)

4
Ashley Grenon

ポップアップウィンドウで、パラメーターを使用してメソッドShow()をオーバーロードします。

Public Overloads Sub Show(Caller As Window)
    Me.Owner = Caller
    MyBase.Show()
End Sub

次に、メインウィンドウで、オーバーロードされたメソッドShow()を呼び出します。

Dim Popup As PopupWindow

Popup = New PopupWindow
Popup.Show(Me)
4
Eric Tremblay

いくつかのスレッドがあり、「最上位」のタグもあります。それを検索するか、この投稿に直接アクセスしてください。

私のアプリケーションでのみ他のすべてのウィンドウの上にウィンドウを保持する方法?

2
Chris Thornton

私はOPです。いくつかの調査とテストの後、答えは次のとおりです。

いいえ、する方法はありません正確にそれ。

1
Sylvain

方法は次のとおりです。「最上位」ウィンドウを他のウィンドウのGotFocusおよびLostFocusイベントにサブスクライブさせ、イベントハンドラーとして次を使用します。

class TopMostWindow
{
    void OtherWindow_LostFocus(object sender, EventArgs e)
    {
        this.Topmost = false;
    }

    void OtherWindow_GotFocus(object sender, EventArgs e)
    {
        this.Topmost = true;
    }
}
1
Juan Campa

これをWindowsタグに追加できます

WindowStartupLocation="CenterScreen"

次に、続行するためにユーザーに確認してもらいたい場合に表示することもできます

YourWindow.ShowDialog();

最初にTopMostパラメーターなしで試してみて、結果を確認します。

0
paradisonoir

私はちょうど同じ問題に出くわし、MVVMを使用して所有者を設定する際に問題が見つかりました。本番環境でアプリがクラッシュすることはありませんでした。ウィンドウのURIを使用してウィンドウを開くコマンドを含むウィンドウマネージャービューモデルがあります。アプリをクラッシュさせることなく、所有者をApp.MainWindowに設定できませんでした。

そのため、所有者を設定する代わりに、ウィンドウのTopMostプロパティを、アプリケーションが現在アクティブかどうかを示すウィンドウマネージャビューモデルのプロパティにバインドしました。アプリケーションがアクティブな場合、ウィンドウは希望します。アクティブでない場合は、他のウィンドウでカバーできます。

ビューモデルに追加したものを次に示します。

 public class WindowManagerVM : GalaSoft.MvvmLight.ViewModelBase
    {
        public WindowManagerVM()
        {
            App.Current.Activated += (s, e) => IsAppActive = true;
            App.Current.Deactivated += (s, e) => IsAppActive = false;
        }

        private bool _isAppActive = true;
        public bool IsAppActive
        {
            get => _isAppActive;
            set
            {
                if (_isAppActive != value)
                {
                    _isAppActive = value;
                    RaisePropertyChanged(() => IsAppActive);
                }
            }
        }
    }

これを実装するXAMLは次のとおりです(Locatorという名前のアプリの静的リソースとしてViewModelLocatorでMVVMライトを使用しています)。

<Window Topmost="{Binding WindowManager.IsAppActive, Source={StaticResource Locator}}"/>
0
Chaya Sulman

私も同じ問題に直面し、Googleに続いてこの質問に答えました。最近、私は次のことがうまくいったことを発見しました。

CustomWindow cw = new CustomWindow();
cw.Owner = this;
cw.ShowDialog();
0
user3104278

これを試して:

Popup.PlacementTarget = sender as UIElement;
0
Satya Prakash

私はちょうどこの同じ問題に出くわしました。複数のWPFウィンドウを持つデスクトップアプリがあり、カスタムスプラッシュスクリーンをアプリの他のウィンドウの上にのみ配置する必要がありました。スプラッシュスクリーンが表示されたときに他のウィンドウは開きませんが、認証後にスプラッシュスクリーンからMainWindowを開きます。だから私は@GlenSlaydenがやったことと似たようなことをしたが、コードビハインドでは、私が言ったように、MainWindowがバインドできないので:

private void SplashScreen_ContentRendered(object sender, EventArgs e)
{
    // User authentication...
    // ...

    MainWindow mainWindow = new MainWindow();
    SetBinding(SplashScreen.TopmostProperty, new Binding("IsVisible"))
    {
        Source = mainWindow,
        Mode = BindingMode.OneWay,
        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
    };
    mainWindow.Show();
}

私のプログラムがMainWindowから他のすべてのウィンドウを読み込んでいる間、スプラッシュスクリーンは一番上にありますが、プログラムがユーザーを認証している間、それは一番上ではありません。これは、この問題の解決策に最も近いものです。私のプログラムが認証後にロードされている間、他のすべてのアプリケーションの上位にあるため、完璧ではありませんが、私の場合はそう長くはかかりません。

0
Meloviz

C#を学習して、同様の状況に出くわしました。しかし、私が役立つと思う解決策を見つけました。ずっと前に考えたことがあるかもしれません。これは新しいプロジェクトの開始からのものですが、どのプロジェクトでも使用できます。

1)新しいプロジェクトを開始します。

2)[プロジェクト]、[新しいWindowsフォーム]の順に移動し、[Windowsフォーム]を選択して、Splashという名前を付けます。

3)サイズ、背景、テキストなどを必要に応じて設定します。

4)Splash.csフォームのプロパティの下で、開始位置:CenterScreenおよびTopMost:true

5)form1は「System.Threadingを使用」を追加します。

6)クラスの下のform1に「Splash splashscreen = new Splash();」を追加

7)form1は「splashscreen.Show();」を追加しますおよび「Application.DoEvents();」

8)form1「イベント」>>「フォーカス」>>「アクティブ化」に「Thread.Sleep(4000); splashscreen.Close();」を追加します。

9)「公開スプラッシュ」の下にSplash.csを追加「this.BackColor = Color.Aqua;」を追加/任意の色を使用できます

10)これはForm1.csのコードです

public partial class Form1 : Form
{
    Splash splashscreen = new Splash();
    public Form1()
    {
        InitializeComponent();
        splashscreen.Show();
        Application.DoEvents();

    }

    private void Form1_Activated(object sender, EventArgs e)
    {
        Thread.Sleep(4000);
        splashscreen.Close();
    }
}

11)これはSplash.csのコードです

public partial class Splash : Form
{
    public Splash()
    {
        InitializeComponent();
        this.BackColor = Color.Aqua;
    }
}

12)スプラッシュで何もしないと、最初のフォームをアクティブにする必要がある間、画面が一番上に表示されないことがわかりました。スレッドカウントはx秒後にスプラッシュが消えるため、プログラムは正常です。

0
John B

これはどう:

Private Sub ArrangeWindows(Order As Window())
    For I As Integer = 1 To Order.Length -1
        Order(I).Owner = Order(I - 1)
    Next
End Sub
0
Error404