[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口相关的知识,希望对你有一定的参考价值。

原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

                           [WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口

                                             周银辉

现象:
大家可以试试下面这个很有趣但会带来Defect的现象:当我们将子窗口按照ShowDialog()的方式显示出来的时候,很明显该窗口是模式化的(即主窗口等待该窗口的返回,主窗口将不相应用户输入),但如果此时将子窗口的Visibility设置成Visibility.Hidden来隐藏窗口,然后再将Visibility设置成Visibility.Visible来再次显示子窗口,此后子窗口便是非模式的了(即主窗口和子窗口一样相应用户输入)

案例:
当用户不操作软件达到一定的时间间隔后,软件会隐藏该软件当前显示的所有窗口,并弹出“锁定窗口”,当用户手动解锁后,“锁定窗口”隐藏,其它所有窗口重新显示出来。

对于上述案例中的窗口,如果使用设置Visibility的方式来显示或隐藏窗口,如果被隐藏的窗口是模式对话框的化,便会在重新显示时出现上述问题。

解决方案:
可以用一个相对简单的方式来解决这个问题:“隐藏” 就是 "看不见”, “把窗口扔到显示屏幕之外”就是“看不见”。(这属于“WO,KAO"类的方案,而非”WOW,SAI“,不过却能很好地工作。”写软件就是骗入“----用高科技骗人的眼睛、耳朵,写游戏就更得会骗人了)

代码:

public class WindowVisibilityHelper : DependencyObject
    {
        
public static bool GetIsVisible(DependencyObject obj)
        {
            
return (bool)obj.GetValue(IsVisibleProperty);
        }

        
public static void SetIsVisible(DependencyObject obj, bool value)
        {
            obj.SetValue(IsVisibleProperty, value);
        }

        
public static readonly DependencyProperty IsVisibleProperty =
            DependencyProperty.RegisterAttached(
"IsVisible"typeof(bool), 
            
typeof(WindowVisibilityHelper), 
            
new PropertyMetadata(true, IsVisiblePropertyChangedCallback));

        
private static void IsVisiblePropertyChangedCallback(DependencyObject obj, 
            DependencyPropertyChangedEventArgs e)
        {
            var window 
= (Window)obj;
            var visible 
= (bool)e.NewValue;

            
if (!visible)
            {
                SetWindowState(window, window.WindowState);
                
if (window.WindowState == WindowState.Maximized)
                {
                    window.WindowState 
= WindowState.Normal;
                }

                SetWindowLocation(window, 
new Point(window.Left, window.Top));
                window.Left 
= -100000;
                window.Top 
= -100000;

                SetWindowIsShowInTaskBar(window, window.ShowInTaskbar);
                window.ShowInTaskbar 
= false;
            }
            
else
            {
                window.WindowState 
= GetWindowState(window);

                Point loc 
= GetWindowLocation(window);
                window.Left 
= loc.X;
                window.Top 
= loc.Y;

                window.ShowInTaskbar 
= GetWindowIsShowInTaskBar(window);

                window.Activate();
                window.BringIntoView();

            }
        }

        
private static Point GetWindowLocation(DependencyObject obj)
        {
            
return (Point)obj.GetValue(WindowLocationProperty);
        }

        
private static void SetWindowLocation(DependencyObject obj, Point value)
        {
            obj.SetValue(WindowLocationProperty, value);
        }

        
private static readonly DependencyProperty WindowLocationProperty =
            DependencyProperty.RegisterAttached(
"WindowLocation"typeof(Point), 
            
typeof(WindowVisibilityHelper), new UIPropertyMetadata(new Point()));


        
private static WindowState GetWindowState(DependencyObject obj)
        {
            
return (WindowState)obj.GetValue(WindowStateProperty);
        }

        
private static void SetWindowState(DependencyObject obj, WindowState value)
        {
            obj.SetValue(WindowStateProperty, value);
        }

        
private static readonly DependencyProperty WindowStateProperty =
            DependencyProperty.RegisterAttached(
"WindowState"typeof(WindowState), 
            
typeof(WindowVisibilityHelper), new UIPropertyMetadata(WindowState.Normal));


        
private static bool GetWindowIsShowInTaskBar(DependencyObject obj)
        {
            
return (bool)obj.GetValue(WindowIsShowInTaskBarProperty);
        }

        
private static void SetWindowIsShowInTaskBar(DependencyObject obj, bool value)
        {
            obj.SetValue(WindowIsShowInTaskBarProperty, value);
        }

        
private static readonly DependencyProperty WindowIsShowInTaskBarProperty =
            DependencyProperty.RegisterAttached(
"WindowIsShowInTaskBar"typeof(bool), 
            
typeof(WindowVisibilityHelper), new UIPropertyMetadata(true));



    }


 

 

 

 

以上是关于[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何使WPF弹出式窗口不被隐藏在主应用程序

WPF如何把隐藏控件显示出来

打开第二个窗口后隐藏主窗口?另外,当第二个窗口被用户关闭时,主窗口如何重新出现?

显示警报后隐藏模式弹出窗口

C#,WPF,Visibility类型为Visible后无法转为Collapsed,显示后隐藏

WPF 窗口居中 & 变更触发机制