2009-03-02 3 views
17

거기에 두 CLR 속성 INotifyPropertyChangedINotifyCollectionChanged을 구현사이의 바인딩 수 있습니다 (그렇지 않으면 BCL 또는) 프레임 워크를 바인딩 데이터?데이터 바인딩 POCO 속성

var binding = new Binding(); 
binding.Source = someSourceObject; 
binding.SourcePath = "Customer.Name"; 
binding.Target = someTargetObject; 
binding.TargetPath = "Client.Name"; 
BindingManager.Bind(binding); 

경우 someSourceObjectsomeTargetObjectINotifyPropertyChanged을 구현 단지 포항 강판이다 : 같은 것을 할 수 있어야한다 보인다. 그러나이 문제에 대한 BCL 지원을 알지 못하며이를 허용하는 기존 프레임 워크가 있는지 확실하지 않습니다.

업데이트 : 사용 가능한 기존 라이브러리가 없다는 것을 감안할 때, 필자는 자신의 글을 쓰려고했다. 이용 가능하다. here.

감사

답변

10

공백을 채우기 위해 Truss을 썼습니다.

1

AutoMapper은 두 인스턴스 사이의 값을 복사 할 수 있지만이 자동으로 일어날 수 있도록하기 위해 자신의 코드를 작성해야합니다.

1

아마도 Bindable LINQ 또는 continuous linq 일 수 있습니다. 실제로 실제 "파생 된 속성"인 모델 속성을 추가하여 데이터를 업데이트하려는 경우 UI를 쉽게 바인딩 할 수 있도록이 두 프레임 워크가 도움이됩니다.

7

저는 라이브러리에 대해 알지 못합니다. 그러나 당신은 매우 쉽게 직접 작성할 수 있습니다.

저는 여기에 간단한 두 속성 사이의 바인딩 두 가지 방법으로 데이터를 설정하는 몇 분 노크 근거는 다음과 같습니다 물론

public static class Binder 
{ 

    public static void Bind(
     INotifyPropertyChanged source, 
     string sourcePropertyName, 
     INotifyPropertyChanged target, 
     string targetPropertyName) 
    { 
     var sourceProperty 
      = source.GetType().GetProperty(sourcePropertyName); 
     var targetProperty 
      = target.GetType().GetProperty(targetPropertyName); 

     source.PropertyChanged += 
      (s, a) => 
      { 
       var sourceValue = sourceProperty.GetValue(source, null); 
       var targetValue = targetProperty.GetValue(target, null); 
       if (!Object.Equals(sourceValue, targetValue)) 
       { 
        targetProperty.SetValue(target, sourceValue, null); 
       } 
      }; 

     target.PropertyChanged += 
      (s, a) => 
      { 
       var sourceValue = sourceProperty.GetValue(source, null); 
       var targetValue = targetProperty.GetValue(target, null); 
       if (!Object.Equals(sourceValue, targetValue)) 
       { 
        sourceProperty.SetValue(source, targetValue, null); 
       } 
      }; 
    } 
} 

이 코드는 몇 가지 미묘한 없다. 추가 할 수있는 상황이

  • sourcetargetsourcePropertyNametargetPropertyName에 의해 식별되는 특성이
  • 이 두 가지 속성 또한

사이의 유형 호환성을 확인 존재 함을 확인

  • 을 할당되었는지 확인을 포함, 반사 상대적으로 느립니다 (벤치마킹하기 전에 그것을 버리기 전에 이 아니기 때문에이 느립니다). 따라서 컴파일 된 표현 대신.

    마지막으로 문자열로 속성을 지정하면 오류가 발생하기 쉽기 때문에 대신 Linq 식과 확장 메서드를 사용할 수 있습니다. 당신은 당신이 그것을 할 수 DependencyProperty 년대로 속성을 정의하면 다음 대신

    Binder.Bind(source, "Name", target, "Name") 
    

    을 쓰는 당신은

    source.Bind(Name => target.Name); 
    
  • +0

    나는 나의 자신의 쓰기를 고려하고 있었기 때문에 실제로 요구하고 있었다. 바퀴와 모든 것을 재발견하고 싶지 않았어 ... 고마워. –

    +0

    업데이트 : 질문에 내 라이브러리에 연결했습니다. –

    +0

    저는 현 프로젝트에 대해 간단한 barebone 데이터 바인딩 클래스가 필요했습니다. 그리고 위의 방법은 내가 필요로하는 것과 거의 일치합니다. Reflection에 사용 된 속성 이름을 POCO에서 가져 오거나 설정하고 변환 및 서식을 적용하는 두 개의 작업 대리자로 대체했습니다. 나는 다음 프로젝트에서 트러스에게 좋은 시도를 할 것입니다. 왜냐하면 그것은 정말로 나에게 들리는 것 같기 때문입니다. – Larry

    -2

    을 작성할 수 있습니다. WF와 WPF 모두 구현되어 있습니다 (첫 번째 링크는 WPF 용이며, WF는 this입니다). 그래서 어떤 것을 사용할 지 결정해야하지만, 둘 다 당신의 필요에 충분해야합니다.

    +2

    DependencyProperty는 POCO가 아닌 DependencyObject에서 상속 함을 의미합니다. –

    +1

    +1. 다른 말로하면, "당신은 포코 (poco)와 함께 할 수없고 DP만이 할 수 없습니다." – Will

    +0

    어? 당신의 논리가이 유언권을 투표하기 위해 무엇인지 확실하지 않습니다. 어느 제안도 POCO를 포함하지 않으므로 내 요구 사항에 대한 제안으로 충분하지 않습니다. 또 다른 포스트는 이미 POCO로 할 수 있다는 것을 보여주었습니다 - 저는 어려운 작업을 수행하는 프레임 워크를 요구하고 있습니다. –

    0

    작생 속성 비동기 바인딩 동작 간의 바인딩을 완벽하게 지원하는 작은 Bind 프로젝트를 작성했습니다. sintax는 더 간단 할 수 없다 :

    //Two way binding between neasted properties: 
    Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName); 
    
    //On change action execute: 
    Bind 
        .OnChange(()=> client.Personal.Name) 
        .Do(x => clientName = x);