我想知道,将命令放入模型是MVVM中的坏习惯。例如,我ListBox
Image
和Button
。当我点击Button
时,我需要在浏览器中打开网址。所以,我的代码看起来像这样:
<ListBox ItemSource="{Binding Items">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source={Binding ImageSource} />
<Button Content="Open url" Command={Binding OpenUrlCommand}"/>
</StackPanel>
</DataTemplate>
</Listbox.ItemTemplate>
</ListBox>
视图模型:
class MainViewModel:BaseViewModel
{
public ObservableCollection<Model> Items {get;set;}
}
型号:
class Model
{
public string ImageSource {get;set;}
public string Url {get;set;}
public ICommand OpenUrlCommand {get;set;}
public Model()
{
OpenUrlCommand = new RelayCommand(openUrl);
}
public void openUrl()
{
Process.Start(Url); //Open url in browser
}
}
没关系,或者我应该将OpenUrlCommand
移到MainViewModel
?
答案 0 :(得分:5)
您实际应该在Model中实现方法,但在ViewModel中实现命令。这将与MVVM架构更加一致,在这种情况下,根本不需要额外的工作。
在ViewModel中:
class MainViewModel : BaseViewModel
{
private Model _model;
ICommand OpenUrlCommand { get { return new RelayCommand(_model.openUrl); } }
// ...
}
如果你想&#34;发送&#34;来自View的某些网址,您可以使用CommandParameter
进行该操作,并输入RelayCommand
。
更新:
请注意,由于Command绑定所在的DataTemplate是ItemTemplate,因此您应该在某些ItemViewModel
中实现Command,而不是MainViewModel
。然后,将Items
设为ObservableCollection<ItemViewModel>
而不是ObservableCollection<Model>
,并按以下方式初始化集合:
IEnumerable<Model> models= getSomeModelsToStartWith();
var Items = new ObservableCollection<ItemViewModel>(models.Select(m => new ItemViewModel(m));