WPF 사용자 컨트롤 배치
타사에서 사용할 사용자 지정 WPF 사용자 컨트롤을 만들었습니다.내 컨트롤에는 처분 가능한 개인 멤버가 있으며, 포함된 창/애플리케이션이 닫히면 항상 처분 방법이 호출되도록 하고 싶습니다.그러나 사용자 컨트롤은 일회용이 아닙니다.
ID 일회용 인터페이스를 구현하고 Unloaded 이벤트에 가입하려고 했지만 호스트 응용 프로그램이 닫힐 때 호출되지 않습니다.MSDN에서 Unloaded 이벤트가 전혀 발생하지 않을 수 있다고 합니다.또한 사용자가 테마를 변경할 때 두 번 이상 트리거될 수도 있습니다.
가능하다면 특정 폐기 방법을 호출하는 것을 기억하는 내 통제력의 소비자에게 의존하고 싶지 않습니다.
public partial class MyWpfControl : UserControl
{
SomeDisposableObject x;
// where does this code go?
void Somewhere()
{
if (x != null)
{
x.Dispose();
x = null;
}
}
}
지금까지 찾은 유일한 해결책은 Dispatcher의 Shutdown Started 이벤트에 가입하는 것입니다.이것이 합리적인 접근입니까?
this.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
여기서 흥미로운 블로그 게시물: WPF 사용자 컨트롤 폐기(ish)
여기에는 디스패치에 가입하는 것이 언급되어 있습니다.종료 - 리소스를 폐기하기 시작했습니다.
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
};
}
당신은 소멸기를 사용할 때 조심해야 합니다.GC Finalizer 스레드에서 호출됩니다.경우에 따라 해제된 리소스가 생성된 스레드와 다른 스레드에서 해제되는 것을 좋아하지 않을 수 있습니다.
WPF UserControls에 언로드 이벤트를 제공하기 위해 다음과 같은 Interactivity Behavior를 사용합니다.UserControls XAML에 동작을 포함할 수 있습니다. 따라서 모든 UserControl에 논리를 배치하지 않고도 기능을 사용할 수 있습니다.
XAML 선언:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<i:Interaction.Behaviors>
<behaviors:UserControlSupportsUnloadingEventBehavior UserControlClosing="UserControlClosingHandler" />
</i:Interaction.Behaviors>
코드백 핸들러:
private void UserControlClosingHandler(object sender, EventArgs e)
{
// to unloading stuff here
}
동작 코드:
/// <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);
}
}
제 시나리오는 조금 다르지만, 제 사용자 컨트롤을 호스팅하는 상위 창이 닫히거나 닫힐 때를 알고 싶습니다. 뷰(즉, 제 사용자 컨트롤)가 클로즈 뷰의 발표자를 호출하여 일부 기능을 실행하고 정리를 수행해야 합니다. (WPF PRISM 애플리케이션에서 MVP 패턴을 구현하고 있습니다.)
방금 사용자 컨트롤의 Loaded 이벤트에서 ParentWindowClosing 메서드를 ParentwindowClosing 이벤트에 연결할 수 있습니다.이렇게 하면 상위 창이 닫힐 때 사용자 컨트롤이 이를 인식하고 이에 따라 작업할 수 있습니다!
언로드는 모두라고 하지만 4.7에는 거의 존재하지 않습니다.그러나 이전 버전의 를 사용하는 경우에는Net, 로딩 방법으로 다음을 수행합니다.
e.Handled = true;
이전 버전은 로딩이 처리될 때까지 언로드하지 않을 것 같습니다.다른 사람들이 여전히 이 질문을 하는 것을 보기 때문에 게시하는 것이고, 이 질문이 해결책으로 제안된 것을 보지 못했습니다.만지기만 합니다.일년에 몇 번씩 인터넷을 하다가 몇 년 전에 이런 일을 당했습니다.하지만, 저는 로딩이 끝날 때까지 언로드가 호출되지 않는 것처럼 간단한 것인지 궁금합니다.저한테는 효과가 있는 것 같지만, 다시 새로운 것으로.Net 로딩이 처리된 것으로 표시되지 않더라도 항상 언로드를 호출하는 것 같습니다.
사용자 컨트롤에는 소멸자가 있습니다. 사용하는 것이 어떻습니까?
~MyWpfControl()
{
// Dispose of any Disposable items here
}
언급URL : https://stackoverflow.com/questions/502761/disposing-wpf-user-controls
'programing' 카테고리의 다른 글
MongoDB bind_ip은 0.0.0으로 설정하지 않으면 작동하지 않습니다. (0) | 2023.05.01 |
---|---|
Git: 로컬 변경을 실행 취소할 수 없습니다(오류: 경로...가 병합되지 않음). (0) | 2023.05.01 |
목표 C에서 강한 것과 약한 것의 차이 (0) | 2023.04.26 |
로컬 Git 변경을 제거하는 다양한 방법 (0) | 2023.04.26 |
git를 사용하여 푸시된 커밋을 취소하려면 어떻게 해야 합니까? (0) | 2023.04.26 |