Programming

ViewModel의 INotifyPropertyChanged와 DependencyProperty

procodes 2020. 3. 1. 16:02
반응형

ViewModel의 INotifyPropertyChanged와 DependencyProperty


Model-View-ViewModel 아키텍처 WPF 애플리케이션에서 ViewModel을 구현할 때이를 데이터 바인딩 가능하게 만드는 두 가지 주요 선택이있는 것 같습니다. DependencyPropertyView가 바인딩 할 속성에 사용 되는 구현을 보았고 INotifyPropertyChanged대신 ViewModel이 구현되는 것을 보았습니다 .

제 질문은 언제 다른 것을 선호해야합니까? 성능 차이가 있습니까? ViewModel 종속성을 WPF에 제공하는 것이 실제로 좋은 생각입니까? 디자인 결정시 고려해야 할 사항은 무엇입니까?


켄트는이 주제에 대한 흥미로운 블로그를 썼다 : 보기 모델 : DependencyObjects 대 포항 강판을 .

짧은 요약:

  1. DependencyObjects는 직렬화 가능으로 표시되지 않습니다
  2. DependencyObject 클래스는 Equals () 및 GetHashCode () 메서드를 재정의하고 봉인합니다.
  3. DependencyObject에는 스레드 선호도가 있습니다.이 스레드는 작성된 스레드에서만 액세스 할 수 있습니다.

POCO 접근법을 선호합니다. INotifyPropertyChanged 인터페이스를 구현하는 PresentationModel (일명 ViewModel)의 기본 클래스는 http://compositeextensions.codeplex.com 에서 찾을 수 있습니다 .


WPF 성능 가이드에 따르면 DependencyObjects는 INotifyPropertyChanged를 구현하는 POCO보다 성능이 뛰어납니다.

http://msdn.microsoft.com/en-us/library/bb613546.aspx


선택은 전적으로 비즈니스 로직과 UI 추상화 수준을 기반으로합니다. 좋은 분리를 원하지 않으면 DP가 당신을 위해 일할 것입니다.

DependencyProperties는 주로 VisualElements 수준에서 적용되므로 각 비즈니스 요구 사항에 대해 많은 DP를 만들면 좋지 않습니다. 또한 INotifyPropertyChanged보다 DP의 비용이 더 큽니다. WPF / Silverlight를 디자인 할 때 UI와 ViewModel을 완전히 분리하여 언제라도 레이아웃 및 UI 컨트롤을 변경할 수 있도록하십시오 (테마 및 스타일 기반).

이 게시물을 참조하십시오-https: //stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . 링크는 Model-View-ViewModel 패턴에 대한 많은 참조를 가지고 있으며, 이는이 논의와 매우 관련이 있습니다.


표현력 관점에서, 나는 의존성 속성을 사용하는 것을 즐기며의 생각에 울부 짖습니다 INotifyPropertyChanged. string이벤트 구독으로 인한 속성 이름 및 가능한 메모리 누수 외에도 INotifyPropertyChanged훨씬 더 명확한 메커니즘이 있습니다.

종속성 속성은 이해하기 쉬운 정적 메타 데이터를 사용하여 "이 작업을 수행 할 때"를 의미합니다. 우아함에 대한 투표권을 얻는 것은 선언적인 접근 방식입니다.


INotifyPropertyChanged 사용하면 getter 및 속성 설정 코드에 더 많은 로직을 추가 할 수 있습니다.

DependencyProperty 예:

public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );

public String Name
{
    set { SetValue( NameProperty, value ); }
    get { return ( String ) GetValue( NameProperty ); }
}

getter와 setter에서-getSet과 GetValue를 각각 호출하기 만하면됩니다. 프레임 워크의 다른 부분에서는 getter / setter가 호출되지 않고 대신 SetValue, GetValue를 직접 호출하므로 속성 논리가 확실하게 실행됩니다.

INotifyPropertyChanged, 이벤트를 정의합니다 :

public event PropertyChangedEventHandler PropertyChanged;

그런 다음 코드 어디에서나 논리를 가지고 다음을 호출하십시오.

// ...
// Something cool...
// ...

if( this.PropertyChanged != null )
{
    PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}

// More cool stuff that will reliably happen...

이것은 getter / setter 또는 다른 곳에있을 수 있습니다.


종속성 속성은 소스와 데이터 바인딩이 아닌 UI 요소에 대한 (대상으로) 바인딩을 지원하기위한 것입니다. 여기서는 INotifyProperty가 시작됩니다. 순수한 관점에서는 ViewModel에서 DP를 사용해서는 안됩니다.

"바인딩의 소스가 되려면 속성이 종속성 속성 일 필요는 없습니다. CLR 속성을 바인딩 소스로 사용할 수 있습니다. 그러나 바인딩의 대상이 되려면 속성이 단방향 또는 양방향 바인딩을 적용하려면 소스 속성이 바인딩 시스템 및 대상으로 전파되는 변경 알림을 지원해야합니다. 맞춤형 CLR 바인딩 소스의 경우이 속성은 INotifyPropertyChanged를 지원해야합니다. 컬렉션은 INotifyCollectionChanged를 지원해야합니다. "

모든 종속성 개체를 직렬화 할 수 없습니다 (이는 ViewModels 및 DTO (POCO) 사용을 방해 할 수 있습니다).

Silverlight 내의 DP와 WPF와의 차이가 있습니다.

http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx

http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx


나도이 결정을 최근에 고려해야했다.

INotifyPropertyChanged 메커니즘은 상태를 복제하지 않고 기존 비즈니스 로직 프레임 워크에 GUI를 붙일 수 있기 때문에 내 요구에 더 잘 맞는다는 것을 알았습니다. 내가 사용하고있는 프레임 워크에는 자체 관찰자 패턴이 있었고 한 수준의 알림을 다음 수준으로 쉽게 전달할 수있었습니다. 비즈니스 로직 프레임 워크와 INotifyPropertyChanged 인터페이스에서 옵저버 인터페이스를 구현 한 클래스가 있습니다.

DP를 사용하면 상태를 직접 저장하는 백엔드를 정의 할 수 없습니다. .net이 바인딩하려는 모든 상태 항목의 복사본을 캐시하도록해야했습니다. 이것은 불필요한 오버 헤드처럼 보였습니다. 제 상태는 크고 복잡합니다.

따라서 비즈니스 로직에서 GUI로 속성을 노출하는 데 INotifyPropertyChanged가 더 좋습니다.

그것은 속성을 노출하고 다른 GUI 위젯에 영향을 미치기 위해 해당 속성의 변경을 위해 사용자 정의 GUI 위젯이 필요한 곳에서 DP는 간단한 해결책을 입증했습니다.

그래서 GUI에서 GUI 알림에 DP가 유용하다는 것을 알았습니다.


ViewModel 종속성을 WPF에 제공하는 것이 실제로 좋은 생각입니까?

.NET 4.0에는 System.Xaml.dll이 있으므로이를 사용하기 위해 임의의 프레임 워크에 종속 될 필요가 없습니다. PDC 세션에 대한 Rob Relyea의 게시물을 참조하십시오 .

내 테이크

XAML은 개체를 설명하기위한 언어이며 WPF는 설명 된 개체가 UI 요소 인 프레임 워크입니다.

이들의 관계는 논리를 설명하는 언어 인 C # 및 특정 종류의 논리를 구현하는 프레임 워크 인 .NET과 유사합니다.

XAML의 목적은 선언적 객체 그래프입니다. W * F 기술은이 패러다임의 훌륭한 후보이지만 XAML은 독립적으로 존재합니다.

XAML과 전체 종속성 시스템은 WF와 WPF에 대한 별도의 스택으로 구현되었으므로 서로 다른 팀의 경험을 활용하여 팀 간의 종속성을 만들지 않아도됩니다.


종속성 속성은 사용자 지정 컨트롤을 만드는 데 사용됩니다. XAML 디자인 타임에 속성 창에 속성을 표시하기 위해 Intelli-sense를 사용하려면 종속성 속성을 사용해야합니다. INPC는 디자인 타임에 속성 창에 속성을 표시하지 않습니다.


버튼과 같은 사용자가 만든 컨트롤에는 종속성 속성을 사용해야합니다. XAML에서 속성을 사용하고 모든 WPF 기능을 사용하려면 해당 속성이 종속성 속성이어야합니다.

그러나 INotifyPropertyChanged를 사용하면 ViewModel이 더 좋습니다. INotifyPropertyChanged를 사용하면 필요한 경우 getter / setter 논리를 가질 수 있습니다.

INotifyPropertyChanged를 이미 구현 한 ViewModel에 대한 Josh Smith의 기본 클래스 버전을 확인하는 것이 좋습니다.

http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

이것이 ViewModel을 수행하는 방법의 훌륭한 예라고 생각합니다.


DependencyProperty와 INotifyPropertyChanged는 Binding에서 두 가지 다른 용도로 사용된다고 생각합니다. 첫 번째는 속성을 바인딩의 대상으로 설정하고 다른 속성에서 입력을받습니다 ({Binding ...}을 사용하여 속성 설정). 바인딩 값 (바인딩 경로 표현식의 이름)으로 속성 값을 사용하려는 경우 따라서 선택은 단지 기술적 인 것입니다.


INotifyPropertyChanged없이 Presentation Model 에서 블로그에 대해 더 직접적인 접근 방식을 선호합니다 . 데이터 바인딩에 대한 대안을 사용하면 부기 코드없이 CLR 속성에 직접 바인딩 할 수 있습니다. View Model에서 일반 .NET 코드를 작성하면 데이터 모델이 변경 될 때 업데이트됩니다.


선호하는 이유는 단 하나뿐입니다 DependencyObject.-바인딩이 더 잘 작동합니다. 그냥 함께 예를 시도 ListBox하고 TextBox, 데이터로 채우기 목록 INotifyPropertyChanged속성 대 DependencyProperty에서 편집 현재 항목을 TextBox...


속성을 다른 컨트롤에 노출하려면 종속성 속성을 사용해야합니다 ...하지만 알아내는 데 시간이 걸리기 때문에 행운을 빕니다 ...

참고 URL : https://stackoverflow.com/questions/291518/inotifypropertychanged-vs-dependencyproperty-in-viewmodel



반응형