Iva*_*nko 1 c# wpf mvvm mvvm-light
我想知道,将命令放入模型是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>
Run Code Online (Sandbox Code Playgroud)
视图模型:
class MainViewModel:BaseViewModel
{
public ObservableCollection<Model> Items {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
模型:
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
}
}
Run Code Online (Sandbox Code Playgroud)
它是确定,或者我应该移动OpenUrlCommand到MainViewModel?
实际上你应该在Model中实现该方法,但是在ViewModel中实现该命令.这将与MVVM架构更加一致,在这种情况下,根本不需要额外的工作.
在您的ViewModel中:
class MainViewModel : BaseViewModel
{
private Model _model;
ICommand OpenUrlCommand { get { return new RelayCommand(_model.openUrl); } }
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果您想从View中"发送"一些URL,您可以使用CommandParameter它,并进行输入RelayCommand.
更新:请注意,由于Command绑定所在的DataTemplate是ItemTemplate,因此您应该在某些实现Command ItemViewModel,而不是在MainViewModel.然后,创建Items一个ObservableCollection<ItemViewModel>而不是ObservableCollection<Model>,并像这样初始化集合:
IEnumerable<Model> models= getSomeModelsToStartWith();
var Items = new ObservableCollection<ItemViewModel>(models.Select(m => new ItemViewModel(m));
Run Code Online (Sandbox Code Playgroud)