WPF: 코드 뒤에 있는 코드 없이 View Model에서 View로 이벤트 신호를 보내는 방법은 무엇입니까?
저는 꽤 간단한 문제를 가지고 있습니다(나는 희망합니다 :):
MVVM에서 View는 일반적으로 ViewModel의 속성 변경 사항을 수신합니다.그러나 VM 신호가 전송될 때 View가 애니메이션을 시작하거나 창을 닫을 수 있도록 이벤트를 청취하고 싶습니다.
Notify를 사용하여 bool 속성을 통해 수행PropertyChanged(그리고 false에서 true로 변경될 때만 애니메이션을 시작)는 가능하지만, 해킹처럼 느껴집니다. 의미적으로 정확하기 때문에 이벤트를 노출하는 것을 훨씬 선호합니다.
또한 코드 뒤에 코드 없이 하고 싶습니다.viewModel.myEvent += handler
View를 GC'd로 설정하려면 이벤트를 수동으로 등록 취소해야 합니다. WPF Views는 이미 속성을 '약하게' 수신할 수 있으므로 View에서 선언적으로만 프로그래밍하는 것을 훨씬 선호합니다.
하나의 보기에 대해 여러 View 모델을 전환해야 하기 때문에 표준 강력 이벤트 구독도 좋지 않습니다(매번 View를 생성하는 데 CPU 시간이 너무 많이 걸리기 때문입니다).
아이디어 감사합니다(표준 솔루션이 있다면 msdn 링크로도 충분합니다)!
일부 의견:
- 약한 이벤트 패턴을 사용하여 뷰가 뷰 모델의 이벤트에 계속 연결되어 있더라도 뷰가 GC'd가 될 수 있도록 할 수 있습니다.
- 단일 뷰에 대해 이미 여러 VM을 전환하고 있는 경우에는 이를 통해 핸들러를 연결/분리하는 것이 이상적이지 않습니까?
- 정확한 시나리오에 따라 VM에서 보기가 애니메이션, 전환 및 기타 시각적 변경에 대한 트리거로 사용하는 상태 속성을 노출시킬 수 있습니다.시각적 상태 관리자는 이런 종류의 일에 매우 적합합니다.
이것도 제가 씨름했던 것입니다.
다른 사람들이 말하는 것과 비슷하지만 여기 코드 스니펫을 사용한 예가 있습니다.이 예에서는 pub/sub를 사용하여 View가 VM에 의해 실행된 이벤트에 가입하도록 하는 방법을 보여 줍니다. 이 경우에는 GridView를 사용합니다.gv가 VM과 동기화되도록 다시 바인딩...
보기(하위):
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Events;
private SubscriptionToken getRequiresRebindToken = null;
private void SubscribeToRequiresRebindEvents()
{
this.getRequiresRebindToken =
EventBus.Current.GetEvent<RequiresRebindEvent>()
.Subscribe(this.OnRequiresRebindEventReceived,
ThreadOption.PublisherThread, false,
MemoryLeakHelper.DummyPredicate);
}
public void OnRequiresRebindEventReceived(RequiresRebindEventPayload payload)
{
if (payload != null)
{
if (payload.RequiresRebind)
{
using (this.gridView.DeferRefresh())
{
this.gridView.Rebind();
}
}
}
}
private void UnsubscribeFromRequiresRebindEvents()
{
if (this.getRequiresRebindToken != null)
{
EventBus.Current.GetEvent<RequiresRebindEvent>()
.Unsubscribe(this.getRequiresRebindToken);
this.getRequiresRebindToken = null;
}
}
메모리 누수를 방지하기 위해 폐쇄 방법에서 미확인범에게 전화를 겁니다
모델 보기(Pub):
private void PublishRequiresRebindEvent()
{
var payload = new RequiresRebindEventPayload();
payload.SetRequiresRebind();
EventBus.Current.GetEvent<RequiresRebindEvent>().Publish(payload);
}
페이로드 클래스
using System;
using Microsoft.Practices.Composite.Presentation.Events;
public class RequiresRebindEvent
: CompositePresentationEvent<RequiresRebindEventPayload>
{
}
public class RequiresRebindEventPayload
{
public RequiresRebindEventPayload()
{
this.RequiresRebind = false;
}
public bool RequiresRebind { get; private set; }
public void SetRequiresRebind()
{
this.RequiresRebind = true;
}
}
생성자가 Guid를 전달하도록 설정하거나 일부가 에 표시되도록 설정할 수도 있습니다. 이 설정은 Pub에서 설정하고 Sub에서 확인하여 pub/sub가 동기화되는지 확인할 수 있습니다.
imhoy Yand separated
- 상태 - 보기 <-> VM 간에 데이터를 앞뒤로 이동할 수 있습니다.
- 조치 - 모델 기능/서비스를 보기 위해 전화를 걸 수 있습니다.
- 알림 - 보기에 어떤 일이 발생했다는 신호를 보낼 수 있으며 요소의 빛내기, 스타일 전환, 레이아웃 변경, 다른 요소의 초점 맞추기 등과 같은 보기 작업을 수행할 수 있습니다.
당신이 재산 바인딩으로 이것을 할 수 있다는 것은 사실이지만, 그것은 토마스가 언급한 것처럼 해킹에 더 가깝습니다. 항상 저에게 이런 느낌이었습니다.
뷰 모델에서 알림으로 'vmdk'를 수신할 수 있는 제 솔루션은 단순하게 데이터 수집 변경 사항을 수신하고 변경 시 찾고 있는 VM 유형을 확인하고 이벤트를 연결하는 것입니다. 조잡하지만 간단합니다.
내가 정말 원하는 것은 일부 '보기 모델 이벤트' 트리거를 정의한 다음 xaml에 있는 모든 것의 보기 측면에서 반응하고 xaml에서 할 수 없는 것에 대해서만 코드 뒤에 있는 일종의 핸들러를 제공하는 간단한 방법입니다.
Adrianm이 말했듯이, 당신이 당신의 애니메이션을 bool 속성에서 트리거할 때 당신은 실제로 이벤트에 반응하고 있습니다.특히 그 사건은PropertyChanged
WPF 하위 시스템.메모리 누수를 방지하기 위해 메모리를 올바르게 연결/분리하도록 설계되었습니다(이벤트를 직접 배선할 때 이 작업을 수행하는 것을 잊어버릴 수 있으며 그렇지 않으면 GC가 적용되어야 하는 개체에 대한 참조를 활성화하여 메모리 누수를 유발할 수 있습니다).
을 이를 로 할 수 .DataContext
데이터 바인딩을 통해 데이터 컨텍스트의 속성 변경에 올바르게 대응하고 제어할 수 있습니다.
MVVM은 WPF가 제공하는 이러한 모든 기능 때문에 WPF와 특히 잘 작동하는 패턴이며, 속성 변경을 트리거하면 실제로 전체 WPF 하위 시스템을 사용하여 목표를 달성할 수 있습니다. :)
보다 일반적인 질문은 다음과 같습니다. "내 View Model에서 이 이벤트를 처리하려는 이유는 무엇입니까?"
애니메이션과 같은 뷰 전용과 관련된 답변이라면 View Model이 이에 대해 알 필요가 없다고 생각합니다. 코드 뒤에 있음(해당하는 경우), Data/Event/PropertyTrigers 및 최신 VisualStateManager 구조는 훨씬 더 유용하고 View와 View Model 간의 명확한 분리를 유지합니다.
이벤트의 결과로 어떤 일이 "발생"해야 하는 경우에는 CommandManager를 사용하거나, 코드 뒤에서 이벤트를 처리하고 뷰 모델에서 명령을 호출하거나, 시스템에서 연결된 동작을 사용하여 명령 패턴을 사용합니다.상호작용 lib.
어느 쪽이든 View 모델을 최대한 "순수"하게 유지하고 싶을 것입니다. View 모델에 특정한 것이 있으면 잘못된 것일 수 있습니다.:)
언급URL : https://stackoverflow.com/questions/1894329/wpf-how-to-signal-an-event-from-viewmodel-to-view-without-code-in-codebehind
'programing' 카테고리의 다른 글
Gitignore가 작동하지 않음 (0) | 2023.04.26 |
---|---|
이클립스:자동 완성/콘텐츠 지원 사용 (0) | 2023.04.26 |
목록 랜덤화 (0) | 2023.04.26 |
Excel Interop - 다른 워크시트를 모두 추가합니다. (0) | 2023.04.26 |
지정된 문화 또는 중립 문화에 적합한 리소스를 찾을 수 없습니다. (0) | 2023.04.26 |