Bu sayfadaki cevapların bazıları neden yanlış!
esasen:
- Pencere, etkinleştirildiğinde odağı başka bir pencereden uzak tutmamalıdır;
- Pencere gösterildiğinde üst öğesini etkinleştirmemelidir;
- Pencere Citrix ile uyumlu olmalıdır.
MVVM Çözümü
Bu kod Citrix ile% 100 uyumludur (ekranın boş alanı yoktur). Hem normal WPF hem de DevExpress ile test edilmiştir.
Bu yanıt, her zaman diğer pencerelerin önünde küçük bir bildirim penceresi istediğimiz herhangi bir kullanım durumu için tasarlanmıştır (kullanıcı bunu tercihlerde seçerse).
Bu yanıt diğerlerinden daha karmaşık görünüyorsa, bunun nedeni sağlam, kurumsal düzeyde kod olmasıdır. Bu sayfadaki diğer cevapların bazıları basittir, ancak aslında çalışmaz.
XAML - Ekli Özellik
Bu eklenen özelliği UserControl
pencerenin içindeki herhangi bir yere ekleyin . Ekli özellik:
Loaded
Etkinlik tetiklenene kadar bekleyin (aksi takdirde üst pencereyi bulmak için görsel ağacı arayamaz).
- Pencerenin görünür olmasını veya görünmemesini sağlayan bir olay işleyicisi ekleyin.
Herhangi bir noktada, attached özelliğinin değerini çevirerek pencereyi önde olacak ya da olmayacak şekilde ayarlayabilirsiniz.
<UserControl x:Class="..."
...
attachedProperties:EnsureWindowInForeground.EnsureWindowInForeground=
"{Binding EnsureWindowInForeground, Mode=OneWay}">
Yardımcı Yöntem
public static class HideAndShowWindowHelper
{
/// <summary>
/// Intent: Ensure that small notification window is on top of other windows.
/// </summary>
/// <param name="window"></param>
public static void ShiftWindowIntoForeground(Window window)
{
try
{
// Prevent the window from grabbing focus away from other windows the first time is created.
window.ShowActivated = false;
// Do not use .Show() and .Hide() - not compatible with Citrix!
if (window.Visibility != Visibility.Visible)
{
window.Visibility = Visibility.Visible;
}
// We can't allow the window to be maximized, as there is no de-maximize button!
if (window.WindowState == WindowState.Maximized)
{
window.WindowState = WindowState.Normal;
}
window.Topmost = true;
}
catch (Exception)
{
// Gulp. Avoids "Cannot set visibility while window is closing".
}
}
/// <summary>
/// Intent: Ensure that small notification window can be hidden by other windows.
/// </summary>
/// <param name="window"></param>
public static void ShiftWindowIntoBackground(Window window)
{
try
{
// Prevent the window from grabbing focus away from other windows the first time is created.
window.ShowActivated = false;
// Do not use .Show() and .Hide() - not compatible with Citrix!
if (window.Visibility != Visibility.Collapsed)
{
window.Visibility = Visibility.Collapsed;
}
// We can't allow the window to be maximized, as there is no de-maximize button!
if (window.WindowState == WindowState.Maximized)
{
window.WindowState = WindowState.Normal;
}
window.Topmost = false;
}
catch (Exception)
{
// Gulp. Avoids "Cannot set visibility while window is closing".
}
}
}
kullanım
Bunu kullanmak için ViewModel'inizde bir pencere oluşturmanız gerekir:
private ToastView _toastViewWindow;
private void ShowWindow()
{
if (_toastViewWindow == null)
{
_toastViewWindow = new ToastView();
_dialogService.Show<ToastView>(this, this, _toastViewWindow, true);
}
ShiftWindowOntoScreenHelper.ShiftWindowOntoScreen(_toastViewWindow);
HideAndShowWindowHelper.ShiftWindowIntoForeground(_toastViewWindow);
}
private void HideWindow()
{
if (_toastViewWindow != null)
{
HideAndShowWindowHelper.ShiftWindowIntoBackground(_toastViewWindow);
}
}
Ek bağlantılar
Bir bildirim penceresinin her zaman görünür ekrana nasıl geri döndüğünden nasıl emin olacağınıza dair ipuçları için cevabım bakın: WPF'de, bir pencere ekran dışındaysa ekrana nasıl kaydırılır? .