首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >释放WPF用户控件

释放WPF用户控件
EN

Stack Overflow用户
提问于 2009-02-02 10:20:20
回答 6查看 109.4K关注 0票数 127

我已经创建了一个自定义的WPF用户控件,该控件旨在供第三方使用。我的控件有一个可释放的私有成员,我希望确保一旦包含的窗口/应用程序关闭,它的dispose方法就会被调用。但是,UserControl不是一次性的。

我尝试实现IDisposable接口并订阅Unloaded事件,但在主机应用程序关闭时都没有调用。MSDN表示可能根本不会引发卸载事件。它也可能被触发不止一次,即当用户更改主题时。

如果可能的话,我不想依赖我的控件的使用者记得调用特定的Dispose方法。

代码语言:javascript
复制
 public partial class MyWpfControl : UserControl
 {
     SomeDisposableObject x;

     // where does this code go?
     void Somewhere() 
     {
         if (x != null)
         {
             x.Dispose();
             x = null;
         }

     }
 }

到目前为止,我找到的唯一解决方案是订阅Dispatcher的ShutdownStarted事件。这是一个合理的方法吗?

代码语言:javascript
复制
this.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-02-02 10:24:34

有趣的博客文章在这里:Dispose of a WPF UserControl (ish)

它提到了订阅Dispatcher.ShutdownStarted来处理您的资源。

票数 60
EN

Stack Overflow用户

发布于 2009-07-07 22:31:22

你必须小心使用析构函数。这将在GC终结器线程上调用。在某些情况下,您释放的资源可能不喜欢在与创建它们的线程不同的线程上释放。

票数 15
EN

Stack Overflow用户

发布于 2014-10-22 17:07:04

我使用下面的交互行为向WPF UserControls提供一个卸载事件。您可以将行为包含在UserControls XAML中。因此,您无需将逻辑放在每个UserControl中,即可拥有该功能。

XAML声明:

代码语言:javascript
复制
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

<i:Interaction.Behaviors>
    <behaviors:UserControlSupportsUnloadingEventBehavior UserControlClosing="UserControlClosingHandler" />
</i:Interaction.Behaviors>

CodeBehind处理程序:

代码语言:javascript
复制
private void UserControlClosingHandler(object sender, EventArgs e)
{
    // to unloading stuff here
}

行为代码:

代码语言:javascript
复制
/// <summary>
/// This behavior raises an event when the containing window of a <see cref="UserControl"/> is closing.
/// </summary>
public class UserControlSupportsUnloadingEventBehavior : System.Windows.Interactivity.Behavior<UserControl>
{
    protected override void OnAttached()
    {
        AssociatedObject.Loaded += UserControlLoadedHandler;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.Loaded -= UserControlLoadedHandler;
        var window = Window.GetWindow(AssociatedObject);
        if (window != null)
            window.Closing -= WindowClosingHandler;
    }

    /// <summary>
    /// Registers to the containing windows Closing event when the UserControl is loaded.
    /// </summary>
    private void UserControlLoadedHandler(object sender, RoutedEventArgs e)
    {
        var window = Window.GetWindow(AssociatedObject);
        if (window == null)
            throw new Exception(
                "The UserControl {0} is not contained within a Window. The UserControlSupportsUnloadingEventBehavior cannot be used."
                    .FormatWith(AssociatedObject.GetType().Name));

        window.Closing += WindowClosingHandler;
    }

    /// <summary>
    /// The containing window is closing, raise the UserControlClosing event.
    /// </summary>
    private void WindowClosingHandler(object sender, CancelEventArgs e)
    {
        OnUserControlClosing();
    }

    /// <summary>
    /// This event will be raised when the containing window of the associated <see cref="UserControl"/> is closing.
    /// </summary>
    public event EventHandler UserControlClosing;

    protected virtual void OnUserControlClosing()
    {
        var handler = UserControlClosing;
        if (handler != null) 
            handler(this, EventArgs.Empty);
    }
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/502761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档