다음 작업을 올바르게 수행하려고합니다. 나는 UserControl (ProgramView)있다. 뷰 모델 (ProgramViewViewModel)이 있습니다. ProgramView는 Window (ProgramWindow) 내에서 자식 컨트롤로 사용됩니다. ProgramWindow에는 공용 속성 ProgramId가 있으므로 창 사용자는 원하는 프로그램 (데이터 엔터티)을 지정할 수 있습니다. ProgramView에는이 데이터를 표시하는 것이 주된 업무이므로 ProgramId 속성이 있습니다. ProgramWindow는이 사용자 정의 컨트롤의 래퍼 창에 불과합니다.WPF : 자식 UserControl (MVVM) 창이있는 적절한 구성
ProgramViewViewModel에는 ProgramId 속성도 있습니다. 이 속성을 변경하면 다른 모델 (ProgramView가 바인딩 할 수 있음)을 사용하여 뷰 모델 외부에 나타나는 뷰 모델의 작업이 중단됩니다.
ViewView의 작업을 ProgramView 및 ProgramWindow 소비자에게 숨기려고합니다.
이 프로그램 ID는이 모든 계층을 통해 바인딩되어야합니다. ProgramWindow.ProgramId의 변경 사항은 ProgramView.ProgramId로 이동 한 다음 ProgramViewViewModel.ProgramId로 이동해야합니다. 나는 이것을 올바르게 구현하는 방법을 알 수 없다.
현재 나의 세 가지 방법은 세 가지 클래스 모두에서 ProgramId를 DP로 표시하는 것입니다. Window 내에서 Programview가 인스턴스화 된 것을 상상해보십시오 :
<local:ProgramView ProgramId="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ProgramWindow}}, Path=ProgramId}" />
이 부분은 실제로 작동하는 것 같습니다. ProgramView 내에서 속성에 대해 변경된 이벤트를 가져오고 올바른 값을 가진 것으로 보입니다. FindAncestor가 제대로 작동하는 것 같습니다.
그런데 어떻게 ProgramViewViewModel.ProgramId 속성을 동기화해야합니까? 나는 두 가지 방법을 본다. 한 가지 방법은 FindAncestor를 사용하고 ProgramViewViewModel에서 ProgramId를 찾으려면 ProgramViewViewModel 인스턴스 자체에 바인딩을 설정하는 것입니다. 두 가지 단점이 있습니다. ProgramViewViewModel을 사용하여 ProgramId를 종속성 속성으로 표시해야합니다. 나는 이것을 피하고 싶지만 받아 들여질 수 있습니다. 어쨌든, 나는 XAML에서 그것을 성취 할 수 없다.
<local:View.DataContext>
<local:ProgramViewViewModel
ProgramId="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ProgramView}}, Path=ProgramId}" />
</local:View.DataContext>
이것은 작동하지 않습니다. 인스턴스의 인스턴스화 내에서 바인딩 표현식을 도입 할 수없는 것으로 보입니다. FindAncestor는 ProgramView를 찾을 수 없다고보고합니다. 내 이론은 인스턴스가 논리적 인 트리의 외부에 있으므로 부모로 트래버스 할 수 없다는 것입니다.
두 번째 옵션은 ProgramView.ProgramId 속성을 "ProgramId"(DataContext)에 바인딩하는 것입니다. 코드 숨김에 정의 된 속성에 바인딩 식을 지정하는 방법을 알 수 없기 때문에이 작업을 수행 할 수 없습니다. XAML에 필요하지만 실제로 ProgramId가 존재하는 유형입니다. 이 속성을 지정하는 방법을 알 수 없습니다.
수동으로 (ProgramView의 코드 숨김으로) Binding 인스턴스를 만들고 SetBinding (ProgramIdProperty, binding)을 호출하면 값이 더 이상 View 자체로 유입되지 않습니다. 나는 이것이 ProgramWindow에 의해 이전에 설정된 ProgramView.ProgramId의 바인딩을 대체했기 때문에 이것이라고 생각한다. 하나의 속성마다 하나의 바인딩?
나머지 아이디어는 두 개의 ProgramId 속성을 ProgramView에 제공하는 것입니다. 하나는 DataContext에 바인딩되고 다른 하나는 소비자 (ProgramWindow)에 바인딩되도록 공개적으로 사용할 수 있으며, 둘 중 하나를 동기화하는 OnValueChanged 처리기를 작성할 수 있습니다. 이것은 해킹처럼 느껴집니다. 다른 하나는 ProgramView의 코드 숨김 내에서 ProgramView.ProgramId 및 ProgramView.DataContext의 변경 사항을 수동으로 감시하고 직접 값을 전파하는 것입니다. 이 아이디어들 중 어떤 것도 이상적이지 않습니다.
다른 제안 사항을 찾고 있습니다.
두 번째 ProgramIdProxy 속성을 사용하면 작동합니다. 나는 단지 그것을 좋아하지 않는다. – wasabi