2011-12-17 2 views
2

Я недавно начал использовать шаблон MVVM в silverlight, и я не уверен, правильно ли я его использую.Где я могу поставить логику для своей ICommand?

GUI

настоящее время у меня MainView, который имеет выпадающий фондового секторов рынка. Когда пользователь выбирает сектор (например, ENERGY) и нажимает кнопку «Добавить», список списков для этого сектора отображается в списке. Рядом с каждым запасом в списке есть кнопка удаления, которая позволяет удалить отдельный запас из списка.

Я реализовал следующие ViewModels. (Ниже приводится только код)

public class MainViewModel 
{ 
    public SectorViewModel CurrentSector 
    { 
    get; 
    set; 
    } 

    public string SelectedSector 
    { 
    get; 
    set; 
    } 


    public void AddSectorClickedCommand() 
    { 
    CurrentSector = new SectorViewModel(SelectedSector); 
    } 

} 

public class SectorViewModel 
{ 
    public ObservableCollection<StockViewModel> Stocks = new ObservableCollection<StockViewModel>(); 

    public SectorViewModel(string sector) 
    { 
     List<Stocks> stocklist = StockProvider.GetStocks(sector); 
     for each (var s in stocklist) 
     { 
      StockViewModel svm = new StockViewModel(s); 
      svm.Remove+= { //Remove svm from Stocks collection logic 
      Stocks.add(svm); 

     } 
    } 
} 

Мой вопрос: в каком режиме viewmodel лучше всего добавить реализацию кода для кнопки «Удалить» каждой строки в списке? Кнопка Удалить должна удалить StockViewModel из коллекции SectorViewModel.Stocks.

В настоящее время я добавил метод RemoveClicked в StockViewModel (как показано выше). Этот код возвращает событие в SectorViewModel, а метод RemoveStock для SectorViewModel удаляет StockViewModel из коллекции Stock.

Есть ли лучший способ реализовать эту функцию удаления? Я новичок в MVVM и не уверен, что это лучший подход к разработке этой функции, так как SectorViewModel должен регистрироваться в событиях StockViewModel.

+1

мой дизайн выглядит нормально, так как это то, что было сделано здесь http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090016 – caa

ответ

0

Лично мне не нравятся события, потому что вы должны отписаться от них, а также их можно использовать там, где это не подходит.

Я хотел бы использовать параметр конструктора для обработки команды удаления, что-то вроде этого:

public class StockViewModel 
{ 
    public StockViewModel(Stock stock, Action<StockViewModel> removeCommandAction) 
    { 
     //... 
     this.RemoveCommand = new DelegateCommand(() => removeCommandAction(this)); 
    } 
} 

public class SectorViewModel 
{ 
    public SectorViewModel() 
    { 
     //... 
     StockViewModel svm = new StockViewModel(s, this.RemoveStock); 
     Stocks.add(svm); 
    } 

    private void RemoveStock(StockViewModel stock) 
    { 
     //... 
    } 
} 

Другой подход заключается в использовании какого-то шаблона EventAggregator, например, Messenger класс от MVVM света Toolkit , Но я думаю, что это слишком для такой простой задачи:

public StockViewModel(Stock stock, IMessenger messenger) 
{ 
    //... 
    this.RemoveCommand = new DelegateCommand(() => 
     messenger.Send(new NotificationMessage<StockViewModel>(this, RemoveItemNotification))); 
} 

public SectorViewModel(IMessenger messenger) 
{ 
    //... 
    messenger.Register<NotificationMessage<StockViewModel>>(this, msg => 
    { 
     if (msg.Notification == StockViewModel.RemoveItemNotification) 
     { 
      this.RemoveStock(msg.Content); 
     } 
    } 
} 

Кроме того, я слышал, что Silverlight 5 поддерживает привязку к относительному источника. Итак, есть третий подход. Я не уверен, работает ли этот пример, но, по крайней мере, он должен:

<Button Content="Remove" 
    Command="{Binding DataContext.RemoveCommand RelativeSource={RelativeSource AncestorType=ListBox}}" 
    CommandParameter="{Binding}" /> 
public class SectorViewModel 
{ 
    public SectorViewModel() 
    { 
     this.RemoveCommand = new DelegateCommand(obj => this.RemoveStock((StockViewModel)obj)); 
    } 

    public ICommand RemoveCommand { get; set; } 
} 

Последний пример является наиболее предпочтительным, кстати, используется в приложениях WPF, потому что WPF всегда было обязательным RelativeSource.

Смежные вопросы