2016-08-19 1 views
0

2 일 동안 프리즘에 있습니다. 따라서 다음 항해 문제를 설명 할 때 잘못된 가정으로 판단하지 마십시오.Prism RequestNavigate behavior

한 지역과 두 개의 다른보기가 있다고 가정 해 봅시다. 보기 A는 시작부터 사용자 정의 RegionBehavior에 의해 해당 지역에로드됩니다. 내가 사용하는 것은 해당 동작의 RegionManager에서 RequestNavigate입니다. 초기보기를 설정하는 데 더 나은 솔루션을 찾지 못했지만 여기서 중요한 점은 아닙니다.

이제 각보기에 다른보기로 이동할 수있는 버튼이 있습니다. 명령은 각 ViewModel에서 실행되고 RequestNavigate를 다시 호출합니다. 컨테이너 (Autofac)에서 탐색을 위해 뷰를 등록하기 위해 상수를 사용했고 RequestNavigate를 호출하기 위해 동일한 상수를 사용했습니다. 첫눈에 다 잘 작동합니다. 그러나 뷰를 전환 할 때마다 새로운 뷰와 뷰 모델이 생성된다는 사실을 깨달았습니다. 더 나쁜 것은, RegionManager는 이전의 것들에 대한 참조를 여전히 보유하고 있으며, 이것은 메모리 누출 인 것처럼 보입니다. 내 뷰를 싱글 톤으로 등록하는 것으로 전환 할 수는 있지만 여전히 RegionManager가 그렇게 작동하는 이유를 이해하지 못했습니다. 왜 그는 그가 이미 탐색을 요구하고 새로운 탐색을 만드는 대신 탐색을 요구한다는 견해를 이미 알고 있다는 것을 깨닫지 못합니까? 그럼 내가 그 대신에 상수를 이름으로 사용하고 있습니까?

그런 다음이 게시물 PRISM WPF - Navigation creates new view every time을 발견했으며 실제로이 문제를 해결했습니다. 뷰를 등록하는 데 형식 이름을 사용하자마자 모든 것이 예상대로 작동합니다. 뷰 및 뷰 모델은 처음 사용할 때 만들어지고 다시 탐색을 요청할 때 다시 사용됩니다.

IRegionMemberLifetime을 구현하고 KeepAlive에 false를 반환 할 수 있습니다. 원하는 동작이 아니고 매번 새로운보기 /보기 모델을 만드는 것을 선호하는 경우에 false를 반환 할 수 있습니다. 그리고 적어도 이전 것들은 RegionManager에서 지워집니다. 그리고 지우고 싶지 않고 여전히이 오래된 메모리를 소비하려는 경우 INavigationAware를 구현하고 IsNavigationTarget에서 false를 반환 할 수 있습니다. 이렇게하면 RegionManager는 매번 새 인스턴스를 만들고 이전 인스턴스에 대한 참조를 보유합니다. 반대로 등록 이름이 유형 이름과 같지 않으면 새로운 인스턴스를 작성하는 것을 막을 수 없습니다. 이 경우 IsNavigationTarget에 도달하지 못했는데, 이는 RegionManager가 기존 뷰를 전혀 조회하지 않는다는 것을 알려줍니다. 그렇다면 탐색에 대한 내 견해를 등록한 이름에 따라 왜 여기에 2 가지 다른 행동이 있습니까? 내가 언급 한 추가 속성으로 다른 모든 시나리오를 만들 수 있기 때문에 두 이름이 같은 경우에만 적용되는 동작이 잘못되었다고 생각할 때 잘못 생각합니까?

스티브

답변

1

당신은 컨테이너에 어떤 이름을 가진 뷰 (모델)를 등록합니다. 그런 다음 등록 이름이 주어지면 뷰 (모델)의 인스턴스를 만들 수 있습니다. 이를 통해 RequestNavigate는 뷰 (모델)를 생성하고 등록 이름이 주어지면이를 활성화 할 수 있습니다.

그러나 RequestNavigate가 대상 뷰의 가능한 기존 인스턴스에 대해 영역을 검사 할 때 (그리고 IsNavigationTarget을 요청할 수도 있음) 영역의 뷰 (모델) 인스턴스를 처리해야합니다. 등록 이름을 사용할 수 없으며 컨테이너 만 컨테이너 이름을 알고 있습니다. 따라서 RequestNavigate는 등록 이름이 뷰 유형의 이름 또는 전체 이름이라고 가정합니다.

따라서 모든 기능을 사용하려면 해당 유형 이름으로보기 (모델)를 등록해야합니다. 그 일을하는 편리한 방법이 있습니다 - RegisterTypeForNavigation.