C# WPF/MVVM:如何从ItemsControl将模型绑定到view/viewmodel
我有一个ItemsControl绑定到C# WPF/MVVM:如何从ItemsControl将模型绑定到view/viewmodel,c#,wpf,xaml,.net-4.5,mvvm-light,C#,Wpf,Xaml,.net 4.5,Mvvm Light,我有一个ItemsControl绑定到任务列表。我想把模型Task赋予它的视图TaskView和viewmodelTaskViewModel <UserControl x:Class="TaskView"> <!-- DataContext of UserControl is a single Task (inherited) --> <Border> <Grid Background="{Binding Status, Conv
任务列表
。我想把模型Task
赋予它的视图TaskView
和viewmodelTaskViewModel
<UserControl x:Class="TaskView">
<!-- DataContext of UserControl is a single Task (inherited) -->
<Border>
<Grid Background="{Binding Status, Converter={StaticResource StatusBackgroundColourConverter}}">
<!-- ... -->
</Grid>
</Border>
</UserControl>
我尝试在view属性上绑定如下值:
<views:TaskView Model="{Binding}" />
但是,它不起作用。由于我是C#/.NET的新手,我不知道我的方向是否正确,因为对于一个常见的问题来说,这似乎很复杂
请注意,它正确地呈现了任务列表,因此ItemsControl按预期工作
问题:
以下是关键部分: 型号
namespace Models
{
public class Task
{
public string Id { get; set; }
public Status Status { get; set; }
// And other properties ...
}
}
列表(父项)
视图模型
public class ListViewModel : ActionViewModelBase
{
public ObservableCollection<Task> Tasks { get; set; }
}
TaskView.xaml
<UserControl>
<UserControl.DataContext>
<viewModels.TaskViewModel />
</UserControl.DataContext>
<Border>
<!-- TODO : Read model attributes -->
<Grid Background="{Binding Path=Model.Status, Converter={StaticResource StatusBackgroundColourConverter}}">
<!-- ... -->
</Grid>
</Border>
</UserControl>
您的模型和视图模型零件定义正确,但是您可能需要查看
INotifyPropertyChanged
界面(以启用对模型的双向数据绑定)
视图模型通过DataContext
属性自动传递给用户控件(请参见:)
也许我不知道你正在使用的模式,但是说到MVVM,你不应该从模型中创建viewmodel,从viewmodel中创建视图,而不是让视图处理模型吗?@grek40这在我看来不正确。根据MVVM模式,模型不应该知道ViewModel,ViewModel也不应该知道View。查看MSDN文档中的图片查看图片并意识到,视图和模型之间没有直接联系。诚然,模型不知道viewmodel,但是:viewmodel知道模型,所以说像
新建viewmodel(modelData)
这样的话是合法的。它与viewmodel和view类似。@grek40我同意,但它似乎与您的第一条评论相矛盾,或者我误解了您。通过将模型作为DataContext,我可以读取属性(状态和Id)。换句话说,它是有效的。但是,我的ViewModel不再接收命令。我猜视图和ViewModel不再链接了。取而代之,将ViewModel作为视图的DataContext,将模型作为ViewModel的“DataContext”不是更好吗?在这种情况下,您需要将任务
重命名为任务模型
,并引入一个具有任务
属性的类任务视图模型
。然后将TaskViewModel
的实例放在ObservableCollection
中。这将是完整的MVVM方法,然后您可以将命令放在TaskViewModel
类中。这很有效!简单明了,正是我喜欢的方式!:)虽然有人告诉我,我们不应该像那样实例化ViewModels,但就我个人而言,我对这个解决方案非常满意。
public partial class TaskView
{
public TaskView()
{
InitializeComponent();
}
public Task Model
{
get { return GetValue(ModelProperty) as Task; }
set { SetValue(ModelProperty, value); }
}
public static readonly DependencyProperty ModelProperty =
DependencyProperty.Register("Model", typeof(Task), typeof(TaskView));
}
<UserControl>
<UserControl.DataContext>
<viewModels.TaskViewModel />
</UserControl.DataContext>
<Border>
<!-- TODO : Read model attributes -->
<Grid Background="{Binding Path=Model.Status, Converter={StaticResource StatusBackgroundColourConverter}}">
<!-- ... -->
</Grid>
</Border>
</UserControl>
class TaskViewModel : ActionViewModelBase
{
public Task Model { get; set; }
// ...
}
<DataTemplate DataType="models:Task">
<!-- DataContext of TaskView is a single Task -->
<views:TaskView />
</DataTemplate>
<UserControl x:Class="TaskView">
<!-- DataContext of UserControl is a single Task (inherited) -->
<Border>
<Grid Background="{Binding Status, Converter={StaticResource StatusBackgroundColourConverter}}">
<!-- ... -->
</Grid>
</Border>
</UserControl>