0

모델 속성에 대한 간단한 양방향 데이터 바인딩이 작동하지 않아 문제가 재현되지 않습니다. Visual Studio 2013에서 새 응용 프로그램을 만듭니다 (예 : .NET 용 빈 응용 프로그램 (범용 응용 프로그램) 템플릿 사용). 워크 4.5유니버설 Windows Apps 8.1 데이터 바인딩 문제

Project folders and files

모델

namespace UWP.MVVM.Models 
{ 
    public class PersonModel 
    { 
     public int Id { get; set; } 

     public string FirstName { get; set; } 

     public string LastName { get; set; } 
    } 
} 

기본 모델 뷰

namespace UWP.MVVM.Core 
{ 
    using System.ComponentModel; 
    using System.Runtime.CompilerServices; 

    public class VMBase : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     public void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
     { 
      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

INavigable 인터페이스

namespace UWP.MVVM.Core 
{ 
#if WINDOWS_PHONE_APP 
    using Windows.Phone.UI.Input; 
#endif 

    public interface INavigable 
    { 
     void Activate(object parameter); 

     void Deactivate(object parameter); 

#if WINDOWS_PHONE_APP 
     void BackButtonPressed(BackPressedEventArgs e); 
#endif 
    } 
} 

주요보기 모델

namespace UWP.MVVM.ViewModels 
{ 
    using UWP.MVVM.Core; 
    using UWP.MVVM.Models; 
#if WINDOWS_PHONE_APP 
    using Windows.Phone.UI.Input; 
#endif 

    public class MainViewModel : VMBase, INavigable 
    { 
     private PersonModel person; 

     public MainViewModel() 
     { 
      this.Person = new PersonModel(); 
     } 

     public PersonModel Person 
     { 
      get 
      { 
       return this.person; 
      } 
      set 
      { 
       if (value == this.person) 
       { 
        return; 
       } 

       this.person = value; 
       this.NotifyPropertyChanged(); 
      } 
     } 

     public void Activate(object parameter) 
     { 
      this.Person.FirstName = "Gerrard"; 
     } 

     public void Deactivate(object parameter) 
     { 
     } 

#if WINDOWS_PHONE_APP 
     public void BackButtonPressed(BackPressedEventArgs e) 
     { 
     } 
#endif 
    } 
} 

메인 페이지보기

<Page 
    x:Class="UWP.MVVM.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:UWP.MVVM" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:vm="using:UWP.MVVM.ViewModels" 
    mc:Ignorable="d" 
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <!--<Page.DataContext> 
     <vm:MainViewModel/> 
    </Page.DataContext>--> 

    <Grid Margin="24,24"> 
     <TextBox Header="First Name" 
       Text="{Binding Person.FirstName}"/> 
    </Grid> 
</Page> 

메인 페이지 코드

namespace UWP.MVVM 
{ 
    using UWP.MVVM.Core; 
#if WINDOWS_PHONE_APP 
    using Windows.Phone.UI.Input; 
#endif 
    using Windows.UI.Xaml.Controls; 
    using Windows.UI.Xaml.Navigation; 
    using UWP.MVVM.ViewModels; 

    /// <summary> 
    /// An empty page that can be used on its own or navigated to within a Frame. 
    /// </summary> 
    public sealed partial class MainPage : Page 
    { 
     public MainPage() 
     { 
      this.InitializeComponent(); 

      this.NavigationCacheMode = NavigationCacheMode.Required; 
      this.DataContext = new MainViewModel(); 
     } 

     /// <summary> 
     /// Invoked when this page is about to be displayed in a Frame. 
     /// </summary> 
     /// <param name="e">Event data that describes how this page was reached. 
     /// This parameter is typically used to configure the page.</param> 
     protected override void OnNavigatedTo(NavigationEventArgs e) 
     { 
      base.OnNavigatedTo(e); 
      var navigableViewModel = this.DataContext as INavigable; 
      if (navigableViewModel != null) 
      { 
       navigableViewModel.Activate(e.Parameter); 
      } 

#if WINDOWS_PHONE_APP 
      HardwareButtons.BackPressed += HardwareButtons_BackPressed; 
#endif 
     } 

     protected override void OnNavigatedFrom(NavigationEventArgs e) 
     { 
      base.OnNavigatedFrom(e); 
      var navigableViewModel = this.DataContext as INavigable; 
      if (navigableViewModel != null) 
      { 
       navigableViewModel.Deactivate(e.Parameter); 
      } 

#if WINDOWS_PHONE_APP 
      HardwareButtons.BackPressed -= HardwareButtons_BackPressed; 
#endif 
     } 

#if WINDOWS_PHONE_APP 
     private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e) 
     { 
      var navigableViewModel = this.DataContext as INavigable; 
      if (navigableViewModel != null) 
      { 
       navigableViewModel.BackButtonPressed(e); 
      } 
     } 
#endif 
    } 
} 
뒤에Mode = TwoWay를 TextBox에서 사용하려고 시도했지만 작동하지 않습니다. 그러나 DataBox를 코드 대신 xaml에 설정하면 데이터 바인딩은 Mode = TwoWay 속성 없이도 작동합니다.

이 문제가 발생한 실제 프로젝트에서와 같이 코드 숨김 파일에 DataContext를 설정하려면 MVC- 라이트 라이브러리를 SimpleIoc 컨테이너와 함께 사용하여 뷰 모델 인스턴스를 가져오고 싶습니다. SimpleIoc을 사용하고 뷰 모델 종속성이 SimpleIoc에 의해 주입되고 코드가 훨씬 깨끗해지기 때문에 DataContext를 설정하십시오.

+0

태그를이 질문은 윈도우 (10) 그러나 당신을 통해 유니버설 윈도우 플랫폼에 대한 개발하는 경우 ** UWP **에만 사용해야합니다 UWP 개발을 지원하지 않는 VS 2013을 사용하는 것으로 보입니다. –

+0

유니버설 윈도우 앱이어야합니다. 그 중 하나가 잘못되었습니다. –

답변

1

문제는 PersonModel Person의 변경 사항 만 알립니다. ViewModel은 속성의 변경을 PersonModel으로 알릴 필요가 있습니다. 당신이 MVVM 빛, 당신의 모델 변경 사용하고 있기 때문에

:

public class PersonModel : ObservableObject 
{ 
    public int Id { get; set; } 

    string _FirstName = ""; 
    public string FirstName { 
     get { 
      return _FirstName; 
     } 
     set { 
      Set(ref _FirstName, value); 
     } 
    } 

    public string LastName { get; set; } 
} 
+0

ViewModel과 여기에이 모델에서 INotifyPropertyChanged를 구현하는 것이 좋습니까? 아니면 모델에서만 구현해야합니까? –

+0

MVVM Light에는 ViewModel 용 Model 및 BaseViewModel에 사용되는 ObservableObject가 있습니다. PropertyChanged를 통지하기 위해서 양쪽 모두를 사용할 수 있습니다. 모델을 깨끗하게 유지하려면 ViewModel의'Person' 속성에 대한 PropertyChanged를 발생시킬 수도 있습니다 :'NotifyPropertyChanged ("Person.FirstName");' 도움이된다면 제 대답을 받아 들일 수 있습니다 :) – thang2410199