Содержимое обновления списка MVVM Сохранение выбранного элемента Silverlight

Я много читал о MVVM (в частности, с использованием библиотеки Лорана Бугниона) и постоянно пытаюсь понять, как делать в MVVM вещи, которые в противном случае были бы легкими с исходным кодом.

Вот. только один пример, когда я подозреваю, что поступаю жестко. Если у кого-то есть время прочитать все это, возможно, они прокомментируют разумность моего подхода. :)

У меня есть список, привязанный к ViewModel, например:

<ListBox x:Name="lstFruitBasketLeft" ItemsSource="{Binding FruitBasket}" 
     SelectedItem="{Binding SelectedFruit, Mode=TwoWay}"  Width="150">
<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Center" 
                    HorizontalAlignment="Left" Margin="2">
            <TextBlock Text="{Binding Name}" />
            <TextBlock Text=":" />
            <TextBlock Text="{Binding Quantity}" />
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

ItemSource - это ObservableCollection объектов Fruit:

public class Fruit
{
    public string Name { get; set; }
    public int Quantity { get; set; }

    public Fruit() { }
    public Fruit(string name, int quantity) 
    {
      this.Name = name;
      this.Quantity = quantity;
    }
  }

Он определен в ViewModel как:

// Property FruitBasket
public const string FruitBasketPropertyName = "FruitBasket";
private ObservableCollection<Fruit> _fruitBasket = null;
public ObservableCollection<Fruit> FruitBasket
{
  get { return _fruitBasket; }
  set
  {
    if (_fruitBasket == value)
      return;

    _fruitBasket = value;

    // Update bindings, no broadcast
    RaisePropertyChanged(FruitBasketPropertyName);
  }
}

Связанное свойство SelectedItem выглядит так:

//Property SelectedFruit
public const string SelectedFruitPropertyName = "SelectedFruit";

private Fruit _selectedFruit = null;

public Fruit SelectedFruit
{
  get { return _selectedFruit; }
  set
  {
    if (_selectedFruit == value)
      return;

    var oldValue = _selectedFruit;
    _selectedFruit = value;

    // Update bindings, no broadcast
    RaisePropertyChanged(SelectedFruitPropertyName);
  }
}

Затем список заполняется при построении ViewModel.

Теперь я добавляю RelayCommand к кнопке на странице презентации, которая выполняет метод, увеличивающий количество выбранного элемента. Обратите внимание, что я еще не использую этот параметр, но «Боб» является заполнителем для некоторых изменений на будущее.

<Button x:Name="butMore" Content="More!" HorizontalAlignment="Right" Height="25" Width="75" Margin="4">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <cmd:EventToCommand
                Command="{Binding addMoreCommand}"
                CommandParameter="Bob" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

Вот код для команды:

// Property addMoreCommand
public RelayCommand addMoreCommand
{
  get;
  private set;
}

...

  //Init relays (this is in the constructor)
  addMoreCommand = new RelayCommand(AddFruit, CanExecute);

...

public void AddFruit()
{
  //Increment the fruit
  SelectedFruit.Quantity++;

  //Save the previous selected item
  Fruit oldSelectedItem = SelectedFruit;

  //We have to have a new list in order to get the list box to refresh
  FruitBasket = new ObservableCollection<Fruit>(FruitBasket);

  //Reselect
  SelectedFruit = oldSelectedItem;
}


public bool CanExecute()
{
  return true; //for now
}

Теперь это действительно работает, но у меня есть некоторые проблемы с этим:

Во-первых, я чувствую, что есть много условий, которые должны объединиться, чтобы это сработало, и мне интересно, будет ли мне так повезло, пытаясь переместить немного Telerik Drag и перетащите код в MVVM.

Во-вторых, воссоздание такого списка похоже на довольно низкую производительность.

Наконец, похоже, что это было бы проще в коде позади (хотя я не уверен на 100%, что мне все равно не придется перестраивать этот список).

Есть ли у кого-нибудь какие-либо мысли по поводу моего подхода или, возможно, даже ... предложения по облегчить задачу? Я просто упускаю что-то очевидное?

Спасибо

-Driodilate:]

6
задан maulkye 18 November 2010 в 19:39
поделиться