• [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));



        }


  • 相关阅读:
    区块链|学习笔记(三)
    左神算法之获取栈中最小值
    23种设计模式之适配器模式
    二叉树序列化和反序列化
    归并排序
    通过集合构建RDD或者DataFrame
    内核源码分析——shuffle
    问题
    函数参数
    问题记录
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1345773.html
Copyright © 2020-2023  润新知