MVVM在模型中命令是一种不好的做法?

时间:2016-04-15 17:19:45

标签: c# wpf mvvm mvvm-light

我想知道,将命令放入模型是MVVM中的坏习惯。例如,我ListBox ImageButton。当我点击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

1 个答案:

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