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

简介: 原文:[WPF疑难] 模式窗口被隐藏后重新显示时变成了非模式窗口                           [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 ));



    }


 

 

 

 

目录
相关文章
|
2月前
|
设计模式 前端开发 C#
WPF 项目中 MVVM模式 的简单例子说明
本文通过WPF项目中的加法操作示例,讲解了MVVM模式的结构和实现方法,包括数据模型、视图、视图模型的创建和数据绑定,以及命令的实现和事件通知机制。
|
3月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
99 0
|
3月前
|
开发者 C# UED
WPF多窗口应用程序开发秘籍:掌握窗口创建、通信与管理技巧,轻松实现高效多窗口协作!
【8月更文挑战第31天】在WPF应用开发中,多窗口设计能显著提升用户体验与工作效率。本文详述了创建新窗口的多种方法,包括直接实例化`Window`类、利用`Application.Current.MainWindow`及自定义方法。针对窗口间通信,介绍了`Messenger`类、`DataContext`共享及`Application`类的应用。此外,还探讨了布局控件与窗口管理技术,如`StackPanel`与`DockPanel`的使用,并提供了示例代码展示如何结合`Messenger`类实现窗口间的消息传递。总结了多窗口应用的设计要点,为开发者提供了实用指南。
222 0
|
3月前
|
前端开发 开发者 C#
WPF开发者必读:MVVM模式实战,轻松实现现代桌面应用架构,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离应用程序的逻辑和界面,提高了代码的可维护性和可扩展性。本文介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定和逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种方式,开发者可以构建更加高效和可扩展的桌面应用程序。
159 0
|
3月前
|
前端开发 C# 开发者
WPF开发者必读:MVVM模式实战,轻松构建可维护的应用程序,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离关注点,提高了代码的可维护性和可扩展性。本文详细介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定与逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种模式,开发者可以更高效地构建桌面应用程序。希望本文能帮助你在WPF开发中更好地应用MVVM模式。
179 0
|
3月前
|
C#
WPF/C#:程序关闭的三种模式
WPF/C#:程序关闭的三种模式
61 0
|
3月前
|
设计模式 前端开发 C#
WPF/C#:理解与实现WPF中的MVVM模式
WPF/C#:理解与实现WPF中的MVVM模式
181 0
|
5月前
|
C#
WPF/C#:程序关闭的三种模式
WPF/C#:程序关闭的三种模式
78 3
|
人工智能 C#
WPF自定义控件库之Window窗口
本文以自定义窗口为例,简述WPF开发中如何通过自定义控件来扩展功能和样式,仅供学习分享使用,如有不足之处,还请指正。
247 5
Revit 二次开发添加WPF窗口的办法
Revit 二次开发添加WPF窗口的办法
Revit 二次开发添加WPF窗口的办法