2011-12-08 5 views
3

저는 MVVM을 처음 사용하기에 익숙합니다. 이 길이 목록에서 특정 요소에 바인딩 각 하나컬렉션의 개별 요소에 바인딩

뷰에 대한 내 XAML에서
public List<float> Length 
{ 
    get; 
    set; 
} 

, 나는 여러 텍스트 상자를 가지고 : 난 너무로 구현 공용 속성을 가진보기 모델 클래스가

DimensionConverter는 차원과 같은 값을 형식화하는 IValueConverter 파생 클래스입니다 (예 : 480.0 인치가 화면의 텍스트 상자에서 40'0 "이됩니다). 그리고 다시 문자열로 변환됩니다 (예 : 35'0" 수율 420.0 인치)

내 문제 : List의 각 값이 연결된 TextBox에서 변경 될 때 유효성을 검사 할 수 있어야합니다. 일부에서는 입력 된 값에 따라 목록의 다른 값을 수정해야 할 수 있습니다 (예 : 길이 [0]의 부동 소수점을 변경하면 길이 [4]의 값이 변경되고 화면이 업데이트 됨).

인덱서를 허용하기 위해 속성을 다시 작업 할 수있는 방법이 있습니까? 또는 List의 각 항목에 대한 개별 속성을 만들어야합니까 (정말 List가 불필요합니다)? 본질적으로, 나는 이미 float 콜렉션을 가지고 있기 때문에 수정 된 각 아이템의 유효성을 검사하기 위해 MVVM 코드를 작성할 수 있기를 바랬다.

생각하십니까? (미리 감사드립니다.)

답변

1

List<float> 대신 ObservableCollection<float>을 사용하고 CollectionChanged 이벤트를 처리하여 사용자가 값을 변경하면이를 감지 할 수 있습니다.

+0

항목 목록에서 특정 목록 항목에 바인딩 할 수 없다는 것을 이해하는 한 무엇인가 놓친 적이 있습니까? – sll

+0

그것은 내가 이해 한 것이 아닙니다.분명히 OP는 사용자 입력의 유효성을 검사하려고하므로 사용자가 값을 변경하면 감지해야합니다. –

+0

질문이 완전히 오해 한 것 같습니다. – sll

1

이 마음에 들지 일이겠습니까 :

<ItemsControl ItemsSource="{Binding Length}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <TextBox Text="{Binding Mode=TwoWay, Converter=DimensionConverter}" /> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

당신이 원하는에 가까운

?
전체 목록을 표시하고 IValueConverter가 ConvertBack을 구현하는 한 값을 사용자가 직접 수정할 수 있습니다.

그러면 토마스는 당신이 할 수있는 경우가 ObservableLinkedList

당신이 지금 할 것은 이미 더러운 모습과 코드의 겨우 몇 줄이야 ..

+0

내가 가진 문제는 뷰의 본질입니다. 나는 만들려고 노력하고있어. 본질적으로 뷰는 건물 레이아웃 용이므로 길이 항목은 벽의 길이, 다양한 구성 (직사각형, L 자형, T 자형 등)입니다. 레이아웃은 개별 측정 값을 입력하기 위해 TextBox 컨트롤이 배치 된 다이어그램으로 표시됩니다. 이미 벽 목록이 있으므로 컬렉션의 각 항목에 대한 보일러 플레이트 메서드를 만드는 것이 아니라 바인딩에서 컬렉션에 액세스하기를 바랬습니다. –

1

그것은 좋은 것입니다 확인, 또는 구현했다 않는 INotifyPropertyChanged를 구현하는 클래스를 가져라. 목록의 길이가 일정하다면 프로퍼티를 가진다.

+0

FYI : Length 속성을 제공하는 ViewModel 클래스가 INotifyPropertyChanged를 구현 함 –

1

당신은 당신이 당신이 여기이

public class FloatClassViewmModel : INotifyPropertyChanged 
{ 
    public FloatClassViewmModel() { 
    this.FloatClassCollection = new ObservableCollection<FloatClass>(); 
    foreach (var floatValue in new[]{0f,1f,2f,3f}) { 
     this.FloatClassCollection.Add(new FloatClass(floatValue, this.FloatClassCollection)); 
    } 
    } 

    private ObservableCollection<FloatClass> floatClassCollection; 

    public ObservableCollection<FloatClass> FloatClassCollection { 
    get { return this.floatClassCollection; } 
    set { 
     if (!Equals(value, this.FloatClassCollection)) { 
     this.floatClassCollection = value; 
     this.RaiseOnPropertyChanged("FloatClassCollection"); 
     } 
    } 
    } 

    private void RaiseOnPropertyChanged(string propName) { 
    var eh = this.PropertyChanged; 
    if (eh != null) { 
     eh(this, new PropertyChangedEventArgs(propName)); 
    } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

같은 모델을 사용할 수 있습니다 당신의 ViewModel에 당신의 ViewModel

public class FloatClass : INotifyPropertyChanged 
{ 
    private ICollection parentList; 

    public FloatClass(float initValue, ICollection pList) { 
    parentList = pList; 
    this.Value = initValue; 
    } 

    private float value; 

    public float Value { 
    get { return this.value; } 
    set { 
     if (!Equals(value, this.Value)) { 
     this.value = value; 
     this.RaiseOnPropertyChanged("Value"); 
     } 
    } 
    } 

    private void RaiseOnPropertyChanged(string propName) { 
    var eh = this.PropertyChanged; 
    if (eh != null) { 
     eh(this, new PropertyChangedEventArgs(propName)); 
    } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

에서 뭐지 수있는 모델을 만들 MVVM와 텍스트 입력의 유효성을 검사하려면 xaml 예

<ItemsControl ItemsSource="{Binding Path=FloatClassViewmModel.FloatClassCollection}"> 
    <ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <TextBox Text="{Binding Value, Mode=TwoWay, Converter=DimensionConverter}" /> 
    </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

희망이 도움이

+0

이 방법에 대해 생각해 보았습니다. 나에게 "배관공이 무거워"보이기 때문에 망설이지 만, MVVM에 상당히 익숙하다. 아마도 C++ 시대의 남은 부분 일 것이다. –

관련 문제