gpt4 book ai didi

silverlight - 我将 ICommand 的逻辑放在哪里?

转载 作者:行者123 更新时间:2023-12-03 10:19:45 26 4
gpt4 key购买 nike

我最近开始在 silverlight 中使用 MVVM 模式,但我不确定我是否正确使用它。

图形用户界面

我目前有一个包含股市板 block 组合框的 MainView。当用户选择一个部门(例如能源)并单击添加按钮时,该部门的股票列表将显示在列表框中。列表框中每只股票的旁边都有一个删除按钮,可让您从列表框中删除单个股票。

我已经实现了以下 ViewModel。 (以下只是代码的指示)

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

}
}
}

我的问题是;在哪个 View 模型中最好为列表框中每一行的删除按钮添加代码实现? Remove 按钮应从 SectorViewModel.Stocks 集合中删除 StockViewModel。

我目前已将 RemoveClicked 方法添加到 StockViewModel(如上所示)。此代码将一个事件返回给 SectorViewModel,并且 SectorViewModel 的 RemoveStock 方法从 Stock 集合中删除 StockViewModel。

有没有更好的方法来实现这个删除功能?我是 MVVM 新手,不确定这是否是开发此功能的最佳方法,因为 SectorViewModel 需要注册到 StockViewModel 的事件。

最佳答案

就我个人而言,我不喜欢事件,因为您应该取消订阅它们,并且它们也可以在不合适的地方使用。

我会使用构造函数参数来处理删除命令,如下所示:

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 light 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 支持绑定(bind)到相对源。
所以有第三种方法。我不确定这个例子是否有效,但至少它应该:
<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 绑定(bind)。

关于silverlight - 我将 ICommand 的逻辑放在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8544763/

26 4 0