Я много читал о 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 and Drop в MVVM.
Во-вторых, похоже, что при воссоздании списка такой подход выглядит довольно плохо.
Наконец, кажется, что в коде было бы легче (хотя я не уверен на 100%, что мне все равно не придется перестраивать этот список).
Есть ли у кого-нибудь мысли?на мой подход или, возможно, даже ... предложения, чтобы сделать вещи проще?Я просто упускаю что-то очевидное здесь?
Спасибо
-Дриодилат:]