Привязка к отдельным элементам в коллекции - PullRequest
3 голосов
/ 09 декабря 2011

Я довольно новичок в MVVM, так что терпите.У меня есть класс модели представления с открытым свойством, реализованным следующим образом:

public List<float> Length
{
  get;
  set;
}

В моем XAML для представления у меня есть несколько текстовых полей, каждое из которых связано с определенным элементом в этом списке длины:

  <TextBox Text="{Binding Length[0], Converter=DimensionConverter}" />
  <TextBox Text="{Binding Length[2], Converter=DimensionConverter}" />
  <TextBox Text="{Binding Length[4], Converter=DimensionConverter}" />

DimensionConverter является производным классом IValueConverter, который форматирует значения как измерение (т. Е. 480,0 дюйма становится 40'0 "в текстовом поле на экране) и обратно (т. Е. Занимает 35'0"для строки и получим 420.0 дюймов для источника)

Моя проблема: мне нужно иметь возможность проверять каждое значение в списке, поскольку оно изменяется в соответствующем TextBox.Для некоторых мне может понадобиться изменить другие значения в списке в зависимости от введенного значения (т. Е. Изменение значения с плавающей точкой на Length [0] изменит значение на Length [4] и обновит экран).

Есть ли способ переделать свойство, чтобы учесть индексатор?Или мне нужно создавать отдельные свойства для каждого элемента в списке (что действительно делает список ненужным)?По сути, поскольку у меня уже есть коллекция с плавающей точкой, я надеялся, что смогу написать код MVVM для проверки каждого элемента при его изменении.

Мысли?(и, заранее спасибо)

Ответы [ 4 ]

1 голос
/ 09 декабря 2011

если вы хотите проверить ввод текста с помощью mvvm, то создайте модель, которую вы можете использовать в своей модели просмотра

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;
}

в вашей модели просмотра вы можете использовать модель, подобную этой

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;
}

вот пример xaml

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

надеюсь, это поможет

1 голос
/ 09 декабря 2011

Не будет ли что-то вроде этого:

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

Быть рядом с тем, что вы хотите?
Он отобразит весь список и позволит пользователю изменять значения, которые будут возвращены прямовернуться к списку, если ваш IValueConverter реализует ConvertBack.

Затем выполните, как сказал Томас, проверку или реализуйте ObservableLinkedList

То, что вы делаете в данный момент, выглядитгрязный уже и всего несколько строк кода ..

1 голос
/ 09 декабря 2011

Было бы здорово, если бы у вас был класс, который реализует INotifyPropertyChanged, чтобы иметь свойства при условии, что длина списка постоянна.

1 голос
/ 09 декабря 2011

Вы можете использовать ObservableCollection<float> вместо List<float> и обрабатывать событие CollectionChanged, чтобы определить, когда пользователь изменяет значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...