Mar*_*ath 114 .net c# wpf user-controls dispose
我创建了一个自定义WPF用户控件,供第三方使用.我的控件有一个一次性的私有成员,我想确保一旦包含窗口/应用程序关闭,它的dispose方法将始终被调用.但是,UserControl不是一次性的.我尝试实现IDisposable接口并订阅Unloaded事件,但在主机应用程序关闭时都不会被调用.如果可能的话,我不想依赖我控制的消费者记住调用特定的Dispose方法.
public partial class MyWpfControl : UserControl
{
SomeDisposableObject x;
// where does this code go?
void Somewhere()
{
if (x != null)
{
x.Dispose();
x = null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我找到的唯一解决方案是订阅Dispatcher的ShutdownStarted事件.这是一种合理的方法吗?
this.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
Run Code Online (Sandbox Code Playgroud)
Ray*_*sen 56
有趣的博客文章:
http://geekswithblogs.net/cskardon/archive/2008/06/23/dispose-of-a-wpf-usercontrol-ish.aspx
它提到订阅Dispatcher_ShutDownStarted来处理你的资源.
Ili*_*ski 38
Dispatcher.ShutdownStarted事件仅在应用程序结束时触发.当控件不再使用时,调用处理逻辑是值得的.特别是在应用程序运行时期间多次使用控件时,它会释放资源.所以ioWint的解决方案更可取.这是代码:
public MyWpfControl()
{
InitializeComponent();
Loaded += (s, e) => { // only at this point the control is ready
Window.GetWindow(this) // get the parent window
.Closing += (s1, e1) => Somewhere(); //disposing logic here
};
}
Run Code Online (Sandbox Code Playgroud)
ale*_*joy 10
我使用以下Interactivity Behavior为WPF UserControls提供卸载事件.您可以在UserControls XAML中包含该行为.因此,您可以拥有该功能,而无需将逻辑放在每个UserControl中.
XAML声明:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<i:Interaction.Behaviors>
<behaviors:UserControlSupportsUnloadingEventBehavior UserControlClosing="UserControlClosingHandler" />
</i:Interaction.Behaviors>
Run Code Online (Sandbox Code Playgroud)
CodeBehind处理程序:
private void UserControlClosingHandler(object sender, EventArgs e)
{
// to unloading stuff here
}
Run Code Online (Sandbox Code Playgroud)
行为代码:
/// <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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的情况略有不同,但我想知道当托管我的用户控件的父窗口关闭/关闭时,意图是相同的.视图(即我的usercontrol)应该调用oncloseView上的演示者来执行某些功能并执行清理.(我们正在WPF PRISM应用程序上实现MVP模式).
我只是想在usercontrol的Loaded事件中,我可以将ParentWindowClosing方法连接到Parent windows Closing事件.这样我的Usercontrol可以在父窗口关闭时知道并采取相应的行动!