精华内容
下载资源
问答
  • WPF应用程序的内存有时会成为性能瓶颈 试了许多方式与API函数 最终用的这种方法
  • WPF关闭应用程序,释放Window窗口资源方法 WindowsForm里一个Application.Exit();方法就可以关闭应用程序,释放资源。 WPF里Application类没有该方法,但是有一个Exit的事件驱动,在WPF应用程序里面关闭程序讲究很...

    WPF关闭应用程序,释放Window窗口资源方法

    1. WindowsForm里一个Application.Exit();方法就可以关闭应用程序,释放掉资源。
    2. WPF里Application类没有该方法,但是有一个Exit的事件驱动,在WPF应用程序里面关闭程序讲究很多:

    在WPF应用程序的关闭是有ShutdownMode属性设置,具有3中枚举类型的值:
    1)OnLastWindowClose 应用程序最后一个窗体关闭时关闭应用程序
    2)OnMainWindowClose 应用程序主窗体关闭时关闭应用程序
    3)OnExplicitShutdown 显示调用关闭

    • 1. 在OnExplicitShutdown模式下必须显示调用Application实例的ShutDown方法

    例如:Application.Current.Shutdown(-1);

    Application.Current.ShutdownMode=ShutdownMode.OnLastWindowClose;

    这里Application.Current返回当前应用程序的当前Application实例。
    注意以上不适应XBAP,XBAP在浏览器关闭时自动关闭。
    例如在.cs里面
    protected override void OnClosed(EventArgs e)
    {
    //Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
    //if (this.IsAfreshLogin == true) return;
    Application.Current.Shutdown();
    base.OnClosed(e);
    }
    另外,还有一种强制终止应用程序进程的方法
    **Environment.Exit(0)**可以立即中断程序执行并退出
    这个方法用起来的感觉类似在任务管理器里找到进程并终止,即立刻关闭进程,不管该进程目前有没有工作,在做什么工作。
    在WPF中调用该方法即立即退出,不会等待当前工作完成。
    需求:需要在许多子窗体中关闭整个程序(WPF)
    winform实现:Application.Exit();
    关于WPF的退出

    如果你在创建项目的时候细心的查看一下项目的结构,你会发现里面有一个App.xaml,一见到App我们知道是应用程序的关键了配置了,当然,WPF的启动窗体也在这里面设置的。
    我们可以在App的中配置启动页,如下所示:
    在这里插入图片描述

    当然,我们还可以再App.cs重写OnStartUp来设置要启动的页面来设置启动的页面,如:

    // An highlighted block
    public partial class App : Application 
    { 
    protected override void OnStartup(StartupEventArgs e) 
    { 
    new Login().Show(); 
    base.OnStartup(e); 
    } 
    } 
    

    程序的退出看着挺简单的,调用App.Current.Shutdown();则程序就退出了,这仅适用于简单的情况,接下来用实际的测试来说话:
    在登录窗口,我们给Cancel按钮添加一个事件(以后会详细介绍,现在就双击OK了),然后再里面实现。WPF的退出方法如下所示的:

    • this.Close();// 关闭当前窗口,可以在OnClosing和 OnClosed中捕获消息,在OnClosing的时候,可以取消关闭窗口。
      Environment.Exit(0);// 强制退出,即使有其他的线程没有结束
    • Application.Current.Shutdown();// 关闭当前程序,如果有其他线程没有结束,不会关闭
    • App.Current.Shutdown();// 同Application,没有和App区分出来。

    代码片

    接下来贴出代码:
    测试代码如下:

    // A code block
    var foo = 'bar';
    
    // 
    public Login() 
    { 
    InitializeComponent(); 
    //new MainWindow().Show(); 
    this.Closing += (s, r) => 
    { 
    // 我不是想真的退出,我想保持最小托盘 
    Debug.WriteLine("I'am running,and change status"); 
    r.Cancel = true; 
    Debug.WriteLine("I'am backing"); 
    }; 
    this.Closed += (s, r) => 
    { 
    // 退出了啊 
    Debug.WriteLine("I'am Closed"); 
    }; 
    //new Thread(() => { while (true) { Thread.Sleep(100); Debug.WriteLine("I'am Running"); } }).Start(); 
    } 
    当我们没有启动新线程的时候,打印的消息如下: 
    开始的时候,仅仅在Login中调用不同的方法,打印的消息如下所示: 
    //输出: 
    //I'am running,and change status 
    //I'am backing 
    // 程序没有退出 
    //this.Close(); 
    //输出: 
    //没有输出任何消息,没有调用Closed和Closing 
    // 程序强制退出 
    //Environment.Exit(0); 
    //输出: 
    //I'am running,and change status 执行了方法,但是程序还是强制退出了 
    //I'am backing 
    //I'am Closed 
    // 程序强制退出 
    //Application.Current.Shutdown(); 
    //输出: 
    //I'am running,and change status 执行了方法,但是程序还是强制退出了 
    //I'am backing 
    //I'am Closed 
    //force closed 
    // 程序强制退出 
    //App.Current.Shutdown(); 
    

    注意

    1. 当我们启用新线程的时候,则除Environment.Exit(0),打印几个I’am
      Running之后,程序就完全退出了,但是其他的都没有提出系统。 那么Close在什么时候会退出程序呢?
    2. 如过调用了Close,而在Closing中没有显示的取消退出,则系统可以退出,这种情况仅仅是在没有多余线程,没有其他窗口启动的时候,如果有其他窗口同时启动,则要考虑App.Current.ShutdownMode。
      如果在App里面显示的或者退出系统之前显示的设置了App.Current.ShutdownMode,此时系统也不会有退出不完全的情况,当系统App.Current.ShutdownMode=OnMainWindowClose的时候,此时如果,调用主窗口的Close,则系统会退出(没有残余线程的情况),即使在主窗口中又弹出了其他的窗口。
    3. 如果设置了App.Current.ShutdownMode=OnLastWindowClose,则此时系统不会关闭,什么时候关闭呢?所有的弹出窗口都关闭的情况下会退出系统(没有残余线程的情况)。
    4. 当设置App.Current.ShutdownMode=OnExplicitShutdown的时候,此时较复杂,此时无论什么样的顺序调用Close都不会关闭窗口,必须显示的调用Application.Current.ShutDown()方法,系统才会退出。

    总结

    退出就是:
    Close->Application.Current.ShutDow()->Enviroment.Exit(0)
    弱------------------------------------------------------------------------------>
    Close->退出系统时候要看App的ShutDownModel设置
    如果系统有为释放的线程,或者先释放掉,或者调用Enviroment.Exit(0)
    强制回收,关闭系统

    展开全文
  • WPF使用Mvvm 模式关闭窗口(Window),简单明了。绝对可信
  • 下面小编就为大家带来一篇C#实现关闭窗口而不释放窗口对象的方法 。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 在线程中打开了一个窗体,而且是模态窗体(ShowDialog()),手动关闭这个子窗体后其句柄资源没有释放,已经在子窗体的Unload方法里加了Dispose()方法,将handle=IntPr.Zero了。
  • Wpf Mvvm模式下窗口ShowDialog的实现
  • WPF窗口关闭时结束所有相关线程

    千次阅读 2018-09-10 17:22:00
    程序主窗口的 Closed 事件中添加代码: Process.GetCurrentProcess().Kill(); 转载于:https://www.cnblogs.com/dhqy/p/9621172.html

    程序主窗口的 Closed 事件中添加代码:

    Process.GetCurrentProcess().Kill();

     

    转载于:https://www.cnblogs.com/dhqy/p/9621172.html

    展开全文
  • 今天来和大家聊如何使WPF窗口外部区域可拖动缩放。 问题来源 对于WPF窗口来说,默认的可拖动缩放区域较小。 在某些应用场景下我们期望能够设置一个较大的可拖动的缩放区域。 自定义WindowChrome 有同学马上想到...

    今天来和大家聊如何使WPF在窗口外部区域可拖动缩放。


    问题来源

    对于WPF窗口来说,默认的可拖动缩放区域较小。

    在某些应用场景下我们期望能够设置一个较大的可拖动的缩放区域。

    在这里插入图片描述

    自定义WindowChrome

    有同学马上想到了,通过WindowChromeResizeBorderThickness属性进行设置

    比如下面的方式

    <Window x:Class="WpfApp2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <WindowChrome.WindowChrome>
            <WindowChrome ResizeBorderThickness="100"></WindowChrome>
        </WindowChrome.WindowChrome>
        <Grid Background="Transparent" MouseDown="UIElement_OnMouseDown">
            <Grid Margin="100" Background="White" />
            <Button Width="100" Height="100" Command="Undo" />
        </Grid>
    </Window>
    

    但是ResizeBorderThickness只能向窗口内部扩展,而在外部依然不可以进行拖动缩放

    在这里插入图片描述

    添加外部窗口

    想要在WPF窗口外部能够拖动缩放,问题的关键就在于如何能在外部收到鼠标点击拖动等消息。

    那么实际上我们只需要在主窗口周围添加四个alpha值为1窗口。

    这些窗口用于接受消息,并传递给主窗口进行拖动变化即可实现。

    (注:visual studio就是这样做的,可以通过工具抓到他周围包含了4个宽度为9像素的窗口)

    在这里插入图片描述

    监听主窗口状态变化

    现在我们一共有了5个窗口。

    要想这5个窗口能像一个窗口一样工作,必须要让周围的辅助窗口跟随主窗口的状态变化。

    这里我主要关注主窗口的下面5个事件:

    • LocationChanged
    • SizeChanged
    • StateChanged
    • IsVisibleChanged
    • Closed

    LocationChanged 和SizeChanged主要是通知辅助窗口调整位置和大小,确定包裹在主窗口周围

    StateChanged和IsVisibleChanged用于通知窗口的显示隐藏,避免主窗口隐藏时,辅助窗口还能被拖动

    Closed用于在主窗口关闭后,关闭辅助窗口以及释放资源。

    有了这些事件,辅助窗口就能够跟随主窗口进行变换了。

    通知主窗口

    接下来一个重要的事情就是辅助窗口被点击拖动时,通知主窗口进行拖动缩放。

    这个行为有很多实现方法,最简单的一种是,让辅助窗口假装自己是主窗口的非客户区。

    听着很复杂,实际做起来很简单,就是在辅助窗口被点击时,给主窗口发一个非客户区被点击的win消息。

    例如下面的代码加入到辅助左侧的辅助窗口中,就能让它在接收到windows的鼠标左键点击时,向主窗口发出一个左侧非客户区的border被点击的消息。

    于是主窗口就傻傻的以为自己左侧非客户区的border被点中了,就进入了拖拽缩放的行为。

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                if (msg == (int)WM.LBUTTONDOWN)
                {
                    Win32.PostMessage(new WindowInteropHelper(Owner).Handle,
                        (int) WM.NCLBUTTONDOWN, (int) HitTestValues.HTLEFT,
                        0);
                }
    
                return IntPtr.Zero;
            }
    

    辅助窗口隐藏

    有了双向的通知机制后,需要接下来需要将辅助窗口设置为透明。

    这里参考了毅仔同学的高性能透明窗口做法。

    具体内容不做详细讲解,有兴趣的同学可以参考毅仔同学的博客。

    WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True) - walterlv

    关键代码如下

    //设置窗口非客户区大小为0
    ResizeMode = ResizeMode.NoResize;
    WindowStyle = WindowStyle.None;
    WindowChrome.SetWindowChrome(this, new WindowChrome()
    {
        GlassFrameThickness = new Thickness(-1),
        CaptionHeight = 0
    });
    //设置窗口alpha值为0x01
    Opacity = 1.0 / 255;
    

    效果呈现

    最后就可以得到如下的效果,我们可以在窗口的外部进行拖动,让主窗口进行缩放了。

    在这里插入图片描述

    另外,这里对整个代码做了封装,所以在使用时可以非常简单。

    只需要在xaml中配置一个附加属性即可。

    <Window x:Class="WpfApp2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:extendedResizeBorder="clr-namespace:ExtendedResizeBorder;assembly=ExtendedResizeBorder"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <extendedResizeBorder:ExtendedResizeBorder.ExtendedResizeBorder>
            <extendedResizeBorder:ExtendedResizeBorder Radius="100" />
        </extendedResizeBorder:ExtendedResizeBorder.ExtendedResizeBorder>
        <Grid Background="Transparent" MouseDown="UIElement_OnMouseDown">
            <Grid Margin="100" Background="White" />
            <Button Width="100" Height="100" Command="Undo" />
        </Grid>
    </Window>
    

    代码

    文中对应的代码已经推送到github的dotnet-campus组织下。

    欢迎大家issue和star

    dotnet-campus/ExtendedResizeBorder: Enable WPF window has an outside resizable border


    参考文档:


    本文会经常更新,请阅读个人博客原文: https://xinyuehtx.github.io/ ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

    知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

    展开全文
  • 窗体关闭以后 ViewModel 并没有释放,再次调用改窗体后,前一个ViewModel才释放, 或者是程序关闭以后才释放 ,搞不懂。。。 如果要马上释放ViewModel可以在Window关闭以后将DataContent 设置为null , 这样...


    最近发现一个有趣的事,通过Window.dataContent来设置绑定以后,

    窗体关闭以后 ViewModel 并没有释放,再次调用改窗体后,前一个ViewModel才释放,

    或者是程序关闭以后才释放 ,搞不懂。。。

    如果要马上释放ViewModel可以在Window关闭以后将DataContent 设置为null ,

    这样ViewModel是可以释放的

    下面是测试代码,大神请指教!


    主窗体:

    <Window x:Class="WeakViewModel.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WeakViewModel"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button Content="Win1"  HorizontalAlignment="Left" Margin="367,211,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
            <Button Content="GC" HorizontalAlignment="Left" Margin="128,211,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
        </Grid>
    </Window>

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                TestWindow win = new TestWindow();
                win.Owner = this;
                win.DataContext = ViewModel.Default;
                win.Show();
            }

            private void Button_Click_1(object sender, RoutedEventArgs e)
            {            
                GC.Collect();
            }
        }


    测试窗体:

    <Window x:Class="WeakViewModel.TestWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WeakViewModel"
            mc:Ignorable="d"       
            Title="TestWindow" Height="300" Width="300">
        <Grid>
            <TextBox HorizontalAlignment="Left" Height="23" Margin="96,111,0,0" TextWrapping="Wrap" Text="{Binding Path=Text}" VerticalAlignment="Top" Width="120"/>
        </Grid>
    </Window>

        public partial class TestWindow : Window
        {
            public TestWindow()
            {
                InitializeComponent();
                Closed += TestWindow_Closed;
            }
            ~ TestWindow()
            {
                MessageBox.Show("释放TestWindow");
            }
            private void TestWindow_Closed(object sender, EventArgs e)
            {

                //注释这个行就能看出差别

                DataContext = null;
            }
        }


    测试ViewModel:

        public class ViewModel
        {
            private static WeakReference _default = null;
            private static object locker = new object();
            public static ViewModel Default
            {
                get
                {
                    if(_default==null||!_default.IsAlive)
                    {
                        lock (locker)
                        {
                            _default = new WeakReference(new ViewModel());
                        }
                    }
                    return _default.Target as ViewModel;
                }
            }

            private ViewModel()
            {

            }

             ~ViewModel()
            {
                MessageBox.Show("释放 ViewModel"+Text);
            }

            private string _text = string.Empty;
            public string Text
            {
                get
                {
                    return _text;
                }
                set
                {
                    _text = value;
                }
            }

        }



    展开全文
  • WPF中模态窗口和非模态窗口

    千次阅读 2018-03-14 16:43:42
    概念说明1 模态窗口打开模态窗口后,只要不关闭窗口,鼠标焦点或者...关闭非模态窗口,该窗口将不复存在,会释放窗口的所有资源,所以无法得到该窗口的任何信息。 实例说明1 建立Windows窗体程序ShowAndShowDia...
  • 在winForm应用程序中,窗口间数据的传递是最多的应用之一,尤其是在管理软件当中。 窗口的数据传递,有多种方式,在这篇随笔中主要是阐述一下利用委托如何来传递数据。 在本实例程序中,有两个窗体:一个主...
  • WPF开发教程

    万次阅读 多人点赞 2019-07-02 23:13:20
    ------WPF开发教程 目录 WPF基础入门.... 3 1. WPF基础之体系结构... 3 2. WPF基础之XAML. 9 3. WPF基础之基元素... 23 4. WPF基础之属性系统... 26 5. WPF基础之路由事件... 33 6. WPF基础之布局系统... ...
  • WPF 单例窗口Close()后再Show()

    千次阅读 2014-11-14 11:12:33
    记录一下 WPF 单例窗口Close()后再Show()会报错
  • wpf 多个窗口的显示与隐藏

    千次阅读 2015-08-19 22:41:56
    动画线程是否开启,如果之前存在,关闭,并释放资源 if ( this ._threadGif != null ) { this . _threadGif . Abort () ; this . _threadGif = null ; } //新建一个 lambda 表达示:用来不停的检测...
  • 最近碰到一个窗口close()后资源无法释放的问题,找了很久才发现原来时存在交叉引用,虽然close()但是该form的对象依然被其他对象所引用,所以垃圾收集器并不能回收该form所占的资源。 1 ...
  • WPF之全局快捷键

    千次阅读 2018-07-03 10:19:12
    转自:https://www.cnblogs.com/leolion/p/4693514.html目录1、WPF快捷键实现方式2、全局快捷键设置界面3、Windows API调用4、注册全局快捷键5、快捷键触发 WPF快捷键实现方式 WPF快捷键实现主要有自定义快捷键...
  • WPF窗体的生命周期

    千次阅读 2017-10-10 08:51:47
    和所有类一样,窗口也有生存期,在第一次实例化窗口时生存期开始,然后就可以显示、激活和停用窗口,直到最终关闭窗口。 1、显示窗体 构造函数 Show()、ShowDialog()方法:Show()方法显示非模态窗口,这意味...
  • 那么,现在,大能的VM已经完成了所有的事情,这个窗口V如何才能自动关闭呢? 据我目前少得可怜的WPF知识可知,有两种方案: 一、利用View里的IsEnable属性 。 原理是这样的: 1、UI中的IsEnabled绑定VM中的属性 2、...
  • 在实际应用中,因为涉及到数据访问、消息连接等问题,经常需要实现...参考:WPF 只允许运行一个程序(单例)。 在App.xaml.cs中重写启动函数: public partial class App : Application { System.Threading....
  • WPF 简单的内存优化

    千次阅读 2018-07-12 10:07:53
    WPF的内存问题困扰了很久.众所周知,如果长时间使用WPF的程序,它的内存占有将会持续增长。...这是我觉得WPF唯一不够尽...首先,感谢网友的分享:http://www.dotnetdev.cn/2010/04/wpf内存释放解决方案/这个方法的意思...
  • wpf事件处理

    2019-10-09 20:04:26
    认识WPF的事件 ...当新建一个wpf应用程序,会自动生成一个App....其中App.xam用来设置Application,应用程序的起始文件和资源及应用程序的一些属性和事件的设置,app.xaml.cs是处理应用程序的相关资源和事件 MainWindo...
  • 对话框的窗口标题不会显示在任务栏中的,任务栏仅会显示主窗体的名称。 对于模式对话框(Model Dialog),只有对话框关闭后,背后父窗体才会获得焦点。无模式对话框(Modeless Dialog)没有这样的限制。   那么...
  • WPF 基础知识学习简单总结(一)

    千次阅读 2019-03-18 11:19:12
    1 User32:为许多元素(窗口,按钮,文本框)提供熟悉windows外形 2 GDI/GDI+:为渲染简单形状,文本和图形提供绘图支持。 WPF底层使用DirectX,优势:①可使用丰富的效果;②显卡硬件加速。 三、分辨率无关性 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 561
精华内容 224
热门标签
关键字:

wpf关闭窗口释放资源