2012-12-11 6 views
2

DataGrid 및보기 모델 (MyViewModel1)이 있습니다. DataGrid은 Items 속성 MyViewModel1에 바인딩됩니다. 제약 조건은 MyViewModel1MyClass1 코드를 만질 수 없다는 것입니다.WPF DataGrid/ListView/ListBox에 계산 된 추가 열을 추가하는 방법

public class MyViewModel1 : INotifyPropertyChanged 
{ 
    ... 
    public ObservableCollection<MyClass1> Items { get { ... } } 
    public int ViewModelProperty1 { get { ... } } 
    public int ViewModelProperty2 { get { ... } } 
} 

public class MyClass1 : INotifyPropertyChanged 
{ 
    ... 
    public int Property1 { get { ... } } 
    public int Property2 { get { ... } } 
    public int Property3 { get { ... } } 
} 

나는 DataGrid이 아니라 3 세 알려진 특성을 가진 열뿐만 아니라 Property1, Property2, Property3, ViewModelProperty1ViewModelProperty2에 따라 각 행에 4 열을 보여 드리고자합니다. 예를 들어, 4 번째 열이 Property1 + Property2 + Property3 + ViewModelProperty1 + ViewModelProperty2이라고 가정 해 봅시다. 4 번째 열에는 현재 값이 표시되어야하므로 ViewModelProperty1이 1 씩 증가하면 4 번째 열도 1 씩 증가해야합니다. 내 질문은 : 이것을 할 수있는 나의 선택은 무엇입니까?

나는이 생각할 수 :

  1. 이 입력으로 모든 종속 변수와 함께 IMultiValueConverter를 사용합니다. 이 예제에서는 잘 작동합니다. 여기서 문제는 변수의 상호 작용이보다 복잡 해지면 곧바로 ((Property1 + 2*Property2) * Property3)^(ViewModelProperty1 - ViewModelProperty2)의 경우 5 개의 변수가 'MultiBinding'에 배치되는 순서가 중요 해지고 바인딩에 많은 지식이있어 솔루션이 취약해질 수 있습니다.

  2. 래퍼를 사용하십시오. MyViewModel1에 변화에 등록하는 새로운 클래스 MyViewModel2,에 DataGrid 바인딩 및

    public class MyViewModel2 
    { 
        public MyViewModel2(MyViewModel1 m) { ... } 
        ... 
        public ObservableCollection<MyClass2> Items { get { ... } } 
    } 
    public class MyClass2 : INotifyPropertyChanged 
    { 
        public MyClass2(MyClass1 inner) 
        { 
         InnerClass = inner; 
         InnerClass.NotifyPropertyChanged += InnerClassChanged; 
        } 
        void InnerClassChanged(object o, PropertyChangedEventArgs) 
        { 
         if (PropertyChanged != null) 
          PropertyChanged("Property4"); 
        } 
        public void ViewModelPropertiesChanged 
        { 
         if (PropertyChanged != null) 
          PropertyChanged("Property4"); 
        } 
    
        public MyClass1 InnerClass { get; private set; } 
        public int Property4 
        { 
         get { return InnerClass.Property1+InnerClass.Property2 ... } 
        } 
        public event PropertyChanged; 
    } 
    
    문제는 제가 위에서 언급 한 2 외에 추가로이 문제를 해결하기 위해 존재하는 어떤 방법입니다

(컨버터 같이 보입니다 및 래퍼).

내 질문에 어떤 식 으로든이 예제를 해결하는 가장 좋은 방법은 아닙니다.

+1

정말 깨끗 다른 방법이 없습니다 (예 : 당신은 코드 숨김에 결합 된 데이터 필드를 둘 수 있었다). 그러나 다중 값 변환기가 값 변환을 수행하기 위해 다른 오브젝트를 호출 할 수 있다는 점은 유의할 가치가 있습니다. 잠재적 인 비즈니스 로직을 일부 공유 클래스로 다시 가져 가면 "부서지기 쉬운"상태가 될 수 있습니다. –

답변

0

미안하지만, 나는 당신이 이미 이것을 생각한 것을 보았습니다! 당신의 이의를 이해하지 못합니다.

MultiBinding에는 IMultiValueConverter을 사용할 수 있습니다. IMultiValueConverter 설명서의 예제를 참조하십시오.

(여기에서 : https://stackoverflow.com/a/2002598/360211)

+0

응답 해 주셔서 감사합니다. 더 많은 배경 정보를 제공하기 위해 나는 과거에이 문제에 대해 꽤 많은 시간을 보았습니다. 그리고 제가 다루고있는 실제 사례에는 때로는 더 많거나 때로는이 예가 갖는 5 가지 종속성보다 적습니다. 한 가지 경우로 나는 3 개의 클래스에 15 개의 종속 변수가 퍼져 있었고 거기에서 'MultiBinding'접근법은 비실용적이되었다. 그 점이 정확히 주관적입니다. 2-3 변수가있는 경우에는 종종 '멀티 바인딩'을 사용합니다. 확장 방법과 비슷한 방법이 있거나 연결된 속성이있는 경우 유용합니다. – Peter

+0

뷰 모델이보기에서 너무 멀리 떨어져있는 것처럼 들립니다. 뷰 모델은 뷰에 표시되는 데이터를 나타내야합니다.어떤 라이트 포맷팅, 간단한 산술 연산은 'xaml'에 포함 되어도 괜찮습니다. 그러나 15 개의 변수를 가진 복잡한 계산은 뷰 모델에서 메이저가 빠져 있다는 것을 알려줍니다. 뷰 모델을 직접 만질 수없는 이유는 무엇입니까? – weston

+0

비슷한 'Views'와 'ViewModel'을 공유하는 것과 'View'당 하나의 'ViewModel'을 공유하는 것 사이의 균형이 있습니다. 나는 'View'당 하나의 'ViewModel'을 갖는 것이 유지 관리에 너무 무거우 며, 'IValueConverter'및 'IMultiValueConverter'클래스를 사용하여 여러보기간에 잘 설계된보기 모델을 공유하는 것이 더 좋습니다. 차이점을 보충하십시오. 15 가지 변수의 경우 'ViewModel'(래퍼)이 추가로 발생했지만 'MultiBinding'도 'ViewModel'도 완벽하지 않은 다른 솔루션이 있는지 찾고 있습니다. – Peter

관련 문제