CAFE

댓글

뒤로

MainViewmodel을 통해서 복수의 viewmodel을 사용하고 싶을 때 어찌해야 하나요?

작성자c00012| 작성시간21.06.15| 조회수159| 댓글 17

댓글 리스트

  • 작성자 김예건 작성시간21.06.28 에러 메시지를 자세히 알려주실 수 있을까요? 화면에 보이는건 XAML Binding Failures 밖에 보이지 않네요. 일단 짤린 부분으로 확인해보면, `Convert.ToDouble(p.FourthBoxValue)` 에서 `p.FourthBoxValue` 가 무엇인지 Local 창에서 확인해주세요.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.28 본문에 선언된 converter에서 값을 물고 와야 하는데, 마지막 화면에서 보듯이 "XAML binding failure:cannot find source"라는 메시지가 뜹니다.
  • 답댓글 작성자 김예건 작성시간21.06.28 c00012 오류가 `factor = Convert.ToDouble(p.FourthBoxValue) ` 절에서 발생하는게 아닌가요?

    Local 창에 Exception 에서 InnerException 이 보이도록 해주실 수 있으실까요? StackTrace 도 첨부해주시면 정확하게 볼 수 있을 거 같네요.

    일단 `p.FourthBoxValue`가 string 타입이고 `Convert.ToDouble` 이 해석 못하는 string 값이 입력된게 아닌가 추측됩니다.

    https://docs.microsoft.com/en-us/dotnet/api/system.convert.todouble?view=net-6.0

    만약 바인딩 자체가 안되는거라고 한다면 Binding 하실 때 Path 즉 경로를 잘못 입력하신거라, XAML 또는 View 코드를 보여주셔야 원인 파악이 가능합니다.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.28 김예건 본문 마지막 부분에 해당 XAML code를 붙였습니다.
  • 답댓글 작성자 김예건 작성시간21.06.28 c00012 ```
    <MultiBinding Converter="{StaticResource PLConverter}">
    <Binding ElementName="ProdBox" Path="Text"/>
    <Binding ElementName="Lender" Path="Text"/>
    <Binding ElementName="Amount" Path="Text"/>
    <Binding ElementName="APR" Path="Text"/>
    <Binding ElementName="Terms" Path="Text"/>
    </MultiBinding>
    ```
    `ElementName` 에 해당하는 Element가 올려주신 코드에는 안보이는데, 코드 길이를 줄이시려고 각 Element 를 XAML 에서 생략하신건가요?
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.28 김예건 아닙니다. ProdBox를 제외한 해당 element는 usercontrol에 정의되어 있습니다. xaml 코드 올렸습니다.
  • 답댓글 작성자 김예건 작성시간21.06.29 c00012 그럼 MainWindow 에서 바인딩할 대상인 Element 를 이름으로 탐색을 하는데, MainWindow 는 생성될 때 'Ledger', 'Amount' 등 Element 를 알 수가 없는거군요. 그러면 바인딩이 제대로 연결되지 않습니다. 'PropertyChanged' 이벤트를 연결할 Element 가 Xaml 을 컴파일할 때 존재하지 않기 때문입니다. 만약 ContentControl 로 동적으로 UserControl 인 PersonalLoan 을 주입하는거라면 동적으로 바인딩을 생성해줘야 합니다. 차라리 PersonalLoanVM 을 DataContext 로 지정하셨으니 Element 가 아닌 ViewModel 과 바인딩하시는건 어떨까요? CommandParamter 를 넘기실 필요 없이 PersonalLoanVM 의 속성을 활용해서 커맨드를 실행시키면 됩니다

    https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.data.binding.elementname?view=winrt-20348#remarks
  • 답댓글 작성자 김예건 작성시간21.06.29 c00012 코드로 설명하면,

    TwoWay 바인딩으로 View 에서 데이터가 변경되면 ViewModel 의 데이터도 업데이트합니다.
    ```
    // PersonalLoan
    <TextBox x:Name="Lender" Text="{Binding Lender, Mode=TwoWay}" />
    ```

    CommandParamter 는 주석처리합니다.
    ```
    <Button>
    <!--
    <Button.CommandParameter>
    </Button.CommandParameter>
    -->
    </Button>
    ```
    CommandParamter 대신 ViewModel 의 데이터를 업데이트합니다.
    ```
    private void ShowOffer()
    {
    // ViewModel 내부 변수 활용
    }
    ```
    지금 @c00012 님이 제공해주신 코드는 MVVM 패턴을 제대로 활용하지 못하고 있습니다. 위와 같이 개선하신다면 더 간결하고 클린하게 코드를 작성할 수 있습니다.구체적으로 설명을 하자면, 제공해주신 코드는 ViewModel 에 데이터를 View 에서 View 로 옮겼다가 다시 ViewModel 로 받게 설계되어 있습니다.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.29 김예건 우선 자세하신 답변 감사드립니다. 제안하신 대로 해 보고 안 되는 거 있으면 다시 질문드리겠습니다.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.29 김예건 말씀하신 대로 다음과 같이 코드를 바꿨습니다.
    해당 button의 command parameter를 없애고
    그리고 PersonalLoan의 부분에서 모든 요소를 다음과 같이 바꿨습니다;
    <TextBox x:Name="Lender" Text="{Binding Lender, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" Margin="10" Height="30" FontFamily="Segoe UI" FontSize="18"/>
    ....
    마지막으로
    private void ShowOffer(object param) 부분도 내부변수로 바꾸고 compile했더니 binding failure는 나지 않는데 메시지 박스 자체가 안 뜨네요. 어떻게 된 건지 지적을 부탁드려도 될 까요?
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.29 김예건 그리고 MainViewmodel의 생성자를 다음과 같이 수정했습니다.
    public MainViewModel()
    {
    foreach (object item in Enum.GetValues(typeof(ProdCode)))
    {
    ProdStrings.Add(item.ToString());
    }
    ProdSelectCommand = new RelayCommand<object>(p => ShowSelect(p));
    PersonalLoanVM = new PersonalLoanViewModel();
    }
    이렇게 고치고 돌렸더니 메시지 박스는 뜨는데 아래 같이 뜨네요. 어떻게 해야 하나요? 답변 기다립니다.
    댓글 첨부 이미지 이미지 확대
  • 작성자 김예건 작성시간21.06.30 PersonalLoanViewModel 에 데이터가 입력되지 않는 건지 ViewModel 바인딩이 제대로 되었는지 확인하시면 됩니다. TwoWay 바인딩대로 속성이 변경되는지 BreakPoint 를 설정해서 확인해보세요.

    추측하기로는 PersonalLoanViewModel 를 2개 만드시는게 아닐까 합니다.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.30 확인을 해 봤는데 제 생각에는 PersonalLoanViewModel에 데이터가 입력되지 않는 거 같습니다. 그리고 PersonalLoanViewModel이 2개 만들어진다는 게 무슨 뜻인지요? 같은 instance가 2개가 생긴다는 건가요? 그게 가능한가요? 어찌해야 좋을지 막막하네요... 답변 기다립니다.
  • 답댓글 작성자 김예건 작성시간21.06.30 c00012 동일한 클래스로 2개의 인스턴스가 생긴다는 겁니다. 제가 보기에는 DataContext 가 제대로 설정되지 않아서 경로가 엉뚱하게 되어있어 TwoWay 바인딩이 동작하지 않는 문제이거나, 2개의 인스턴스가 생겨서 하나는 UserControl 에 다른 하나는 MainWindow 에 연결된 문제로 보입니다.

    일단 학습이 좀더 필요하실 듯합니다.
    추천하는 건 아래 사이트를 먼저 학습하신 뒤,
    https://wpf-tutorial.com/
    아래 MS 공식 샘플들 중 중요한 기능들을 살펴보시는 겁니다.
    https://github.com/microsoft/WPF-Samples

    개인적으로 WPF 보다 미래를 위해 MAUI 로 개발하시길 추천드리지만.. 아직 Preview 버전이라 과감하게 추천드리긴 어렵네요. 2021년 11월에 LTS 버전으로 공개되기는 하지만..

    차라리 원격으로 점검을 해드릴까요?
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.06.30 김예건 먼저 답변 감사합니다. 원격 점검은 제 사정상 좀 그렇고요.Github에 소스를 올려놓았는데 그걸 좀 봐주시면 안될까요?
    주소는 https://github.com/c00012/PayEstPractice 입니다.
  • 답댓글 작성자 c00012 작성자 본인 여부 작성자 작성시간21.07.02 김예건님 말씀이 맞았습니다. 경로가 엉뚱하게 되어있었네요. 다 해놓고 마지막에 삼천포로 빠져서 헤멨었네요. 지적 감사드립니다.
  • 작성자 카키104 작성시간21.07.06 와우~ 오늘 봤어요;; 두분 고생하셨습니다.
맨위로

카페 검색

카페 검색어 입력폼
카카오 이모티콘
사용할 수 있는 카페앱에서
댓글을 작성하시겠습니까?
이동시 작성중인 내용은 유지되지 않습니다.