2012-01-04 2 views
0

FINAL 참고 Final solution found in another post방법 창

에 중첩 된 컨트롤에 대한 MVVM에서 WPF 이벤트를 처리하기 위해, 궁극적 인 해결책은에 - 사실 다른 솔루션에서 제공하는 위에 링크로했다. 아무리 노력해도 "요소 이름"구성 요소를 통한 바인딩이 작동하지 않았습니다. 나는 ...은 "상대"가과 계층 DataGrid를에 WPF/MVVM 환경이 너무 복잡하지

<Button Name="btnPrintReport" 
    Command="{Binding DataContext.MyPrintCommand, 
      RelativeSource={RelativeSource FindAncestor, 
          AncestorType={x:Type DataGrid}}}" 
    CommandParameter="{Binding}" 
    Height="16" Width="16" HorizontalAlignment="Center" > 
    <Image Source="MyButtonImage.png" IsHitTestVisible="True"/> 
</Button> 

희망 뭔가를 기반으로 가야했다. 여기 시나리오가 있습니다.

저는 Window (.xaml)와 해당 View Model (.cs)을 가지고 있습니다. 양식은 모든 데이터 바인딩에 문제없이 잘 표시됩니다. (참고 : 이것은 어떤 "상용 프레임 워크"를 통해서도 수행되지 않습니다)

뷰 창에있는 컨트롤 중 하나는 미리 정의 된 모든 열, 제목 및 내용이 포함 된 DataGrid의 사용자 정의 컨트롤입니다 보기가 표시됩니다. 컨트롤은 주 윈도우의 .xaml 파일에 직접 "정의"되어 있지 않지만, 사용자 컨트롤 자체 (이는 명백한 .cs 코드 숨김을 가짐)로 폼에 드롭 되어도 아무 문제없이 작동합니다. 메인 윈도우의 뷰 모델을 가리키는 '의 DataContext "내가 무엇을 찾고 있어요, 이제 데이터 그리드를

<DataGrid AutoGenerateColumns="False" 
    Name="dataMyStuff" 
    ItemsSource="{Binding Path=MyTablePropertyOnViewModel, 
     NotifyOnSourceUpdated=True, 
     NotifyOnTargetUpdated=True}" ... /> 

이있는 사용자 제어와

. 이 데이터 표에는 첫 번째 열에 이미지가있는 열이 있습니다. 이 이미지를 클릭하면이 행이 나타내는 레코드 관련 보고서가 인쇄됩니다 (사용하는 PK 값이 있음). 그렇다면 이미지 "KeyUp"이벤트는 뷰 모델 이벤트 핸들러로 이동하기 때문에 데이터가있는 곳이 어디인지 알려주고 보고서 호출을 준비하는 데 필요한 다른 방법을 알려주는 방법은 무엇입니까? 그리드의 뷰 부분은 사용자에게 코스메틱 디스플레이를위한 것이므로이 컨트롤에 직접 "기능"이 없습니다.

- 편집 - 내가 조쉬와 레이첼의 의견에 따라 내 데이터 그리드를 조정 한

답변에서 진행 당, 그러나 무언가는 여전히 버튼을이었다보고 ... 아주 잘 될 것 같지 않습니다 "Command"인스턴스를 사용하여 필자는 내 뷰 모델에서 "ICommand"인터페이스 개체의 인스턴스에 연결하는 데 필요한대로이를 해석했습니다. 그래서 인스턴스를 만들었습니다. Add, Edit, Save, Cancel, Exit 등의 일반적인 작업에도 사용되므로 명령 처리기가 작동한다는 것을 알고 있습니다. 따라서이 인쇄 용도로 새로운 명령 처리 도구가 있습니다. 간단히하기 위해 항상 실행으로 만들어야하므로 컨트롤의 "CanExecute"부분을 처리 할 메서드가 없습니다. 버튼의 "명령"을 거의 모든 반복으로 설정했습니다. 아직 아무것도 생각할 수 없지만, 여기에 제가 계속하고있는 것을 볼 수 있습니다. 내 뷰 모델 클래스에서

<UserControl> 
    <Data grid columns/template, etc to the button> 
     <DataTemplate> 
     <Button Name="btnPrintReport" 
      Command="{Binding DataContext.MyPrintCommand}" > 
      <Image Source="myPrintImage.png"/> 
     </Button> 
     </DataTemplate> 
    </Data grid columns, etc> 
</UserControl> 

(myICommandButtonHandler는 ICommand의 상속) 제가 보는 것을 이제

private myICommandButtonHandler myPrintCommand; 
public myICommandButtonHandler MyPrintCommand 
{ 
    get { if (myPrintCommand == null) 
      myPrintCommand = new myICommandButtonHandler(myPrint); 
     return myPrintCommand; 
     } 
} 

private void myPrint() 
{ 
    MessageBox.Show("Doing the print job..."); 
} 

. 모든 컨트롤 등을 단계별로 초기화하는 동안 내 창을 호출하려면 메뉴 항목을 클릭하십시오. 먼저 View Model 컨트롤러의 인스턴스를 만듭니다. 그런 다음 창을 호출하고 뷰 모델 컨트롤러를 매개 변수로 전달하므로 창 수준에서 즉시 창 "DataContext"로 설정됩니다. 그런 다음 기본 윈도우가 "InitializeComponents"호출로 이동하여 해당 데이터 격자가 포함 된이 개별 클래스를 포함하여 포함 된 다른 모든 컨트롤을 빌드하기 시작합니다.데이터 컨트롤이있는이 usercontrol의 생성자에는 컨트롤의 나머지 부분이 아직 초기화되지 않았으므로 "데이터 컨텍스트"가 설정되어 있지 않으며 왜 "바인딩"이 " 데이터 그리드의 명령 단추에 바인딩을 시도하면 실패합니다. 그러나 런타임에 실제 데이터가 그리드에서 업데이트되므로 많은 작업이 진행되고 있음을 알고 있습니다.

데이터 그리드의 "ItemsSource"속성이 뷰 모델의 "DataView"속성으로 설정되어 있지만 "단추"의 바인딩에 "MyPrintCommand"처리기가 ​​표시되지 않습니다. 생각은 명중을 얻을 것입니다 .. 그리고 그것의 행동은 메시지 박스를 표시하는 것입니다 (당분간).

+0

몇 가지 현재의 DataRow의 DataContext에 (데이터 개체)를 통과 할 CommandParameter="{Binding }" : 1. UserContorl에 datacontext를 바인딩하는 방법에 대한 코드를 보여줍니다. 2. Button의 바인딩은 'Binding DataContext.MyPrintCommand'를 보입니다. 아마도 Binding MyPrintCommand 또는 Binding ElementName = SomeControl, DataContext.MyPrintCommand 중 하나 여야합니다. –

답변

2

보통 나는 AttachedCommand Behavior을 사용하여 이벤트를 ViewModel 명령에 바인딩 할 수 있습니다. 예를 들어, 당신은 내가 KeyUp 이벤트가 해고 만나지 않도록 이미지가 키보드 포커스를 가질 수 있다고 생각하지 않기 때문에

<Image ... 
     local:CommandBehavior.Event="KeyUp" 
     local:CommandBehavior.Command="{Binding DataContext.PrintCommand, ElementName=dataMyStuff}" 
     local:CommandBehavior.CommandParameter="{Binding }"/> 

는 I,의 keyup가 아닌 다른 이벤트를 사용 좋겠 추천 할 것입니다 사용할 수 있습니다.

더 나은 대안은 버튼을 사용하여 이미지로 템플릿을 덮어 쓰는 것입니다. 이것은 Click 기능을 유지하고 CommandCommandParameter 속성 또한

<Button Command="{Binding DataContext.PrintCommand, ElementName=dataMyStuff}" 
     CommandParameter="{Binding }"> 
    <Button.Template> 
     <Image ... /> 
    </Button.Template> 
</Button> 

에 대한 액세스 권한을 줄 것이다, 단순히 명령

+0

내 질문을 귀하의 답변과 관련하여 업데이트했지만 여전히 고착되었습니다 ... 제가 제공 한 추가 비용이 도움이 될까요? – DRapp

+0

@DRapp 명령 바인딩에서 'ElementName'에 주목하십시오. 각 행의 기본'DataContext'는'PrintCommand'를 가지고 있지 않은 행의 데이터 객체입니다. 바인딩에서'ElementName'을 사용하여 바인딩에서 DataGrid를 찾고 DataGrid라는 DataGrid로 이동하여'DataGrid.DataContext.PrintCommand'에 바인드하도록 지시했습니다. 동일한 객체에'PrintCommand'와'MyTablePropertyOnViewModel'이 모두 포함 된 경우 작동합니다. – Rachel

+0

하지만 데이터 그리드가 인쇄 명령 (ICommand) 핸들러를 가지고 있지 않습니다. VIEW MODEL이하는 일은 ... 그것이 내가 누락 된 부분 인 것 같지만, Element Name 구성 요소도 검토 할 것입니다. – DRapp

1

데이터 템플릿을 내용이있는 단추로 변경하십시오. 버튼의 command 및 commandparameter 등록 정보를 사용하여 인쇄 방법을 호출하십시오. 당신의 viewmodel에서 print 명령을 선언하고 바인드 할 수 있습니다. 매개 변수가 DataGrid의 선택된 행일 수 있습니다.

+0

매우 유망한 사운드이지만, 실제 "버튼"모양을 테두리와 함께 사용하는 것을 피하려고했으나 한 번 시도 할 것입니다. – DRapp

+1

단추 만 이미지로 사용하십시오. 마치 버튼처럼 동작하지만 이미지가 버튼 안에 중첩되어 있지 않은 것처럼 보여줍니다. –