我正在尝试理解这种模式及其背后的所有逻辑。
我不认为这很难,但我仍然没有完成一些简单的任务。
让我们用我写的一个非工作的例子说清楚:
型号:
public class Model
{
public string Name { get; set; }
public string Description { get; set; }
public Categories Category { get; set; }
public Grid PresenterContent { get; set; }
}
视图模型:
public class ViewModel : ViewModelBase
{
private Model _model;
public Model Model
{
get
{
return _model;
}
set
{
if (_model != value)
{
_model = value;
RaisePropertyChanged(() => Model);
}
}
}
public Grid PresenterContent
{
get
{
return Model.PresenterContent;
}
private set { }
}
public ViewModel()
{
Model = new Model();
}
}
查看:
<UserControl.DataContext>
<Binding Source="ViewModel"/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<ContentPresenter Content="{Binding PresenterContent}"/>
</Grid>
现在,我希望这可以在我运行时运行,因为我将DataContext
设置为ViewModel
,其PresenterContent
属性。
(此属性同时位于Model
和ViewModel
,因为我不知道使用子属性,在本例中为Model.PresenterContent
。)
实际发生的是抛出异常:
System.Windows.Data错误:BindingExpression路径错误:'ViewModel''System.String'上找不到'PresenterContent'属性(HashCode = -903444198)。 BindingExpression:Path ='PresenterContent'DataItem ='ViewModel'(HashCode = -903444198); target元素是'System.Windows.Controls.ContentPresenter'(Name =''); target属性是'Content'(类型'System.Object')..
这说明PresenterContent
中没有ViewModel
,这显然是错误的。
如果我尝试绑定到Model
属性,则异常相同。
我做错了什么?
答案 0 :(得分:2)
问题是你正在将UserControl.DataContext的绑定源设置为字符串ViewModel而不是ViewModel的实例(这就是为什么你的错误说“on”ViewModel''System.String'“)
。
为了使它工作,你可以使用:
<UserControl.DataContext>
<vm:ViewModel/>
</UserControl.DataContext>
或者您可以在App.xaml或View资源<vm:ViewModel x:Key="myViewModel"/>
中定义ViewModel,并在您查看中使用:
<UserControl.DataContext>
<Binding Source="{StaticResource myViewModel}"/>
</UserControl.DataContext>
答案 1 :(得分:1)
您不应该在视图模型中放置UserControl(如Grid);这就是View的美丽。根据您的示例,您可能需要像DataGrid这样的控件,它在类似Excel的表中显示内容。请考虑以下事项:
public class Model
{
public string Name { get; set; }
public string Description { get; set; }
public Categories Category { get; set; }
public Grid PresenterContent { get; set; }
}
public class ViewModel : ViewModelBase
{
private ObservableCollection<Model> _model;
public ObservableCollection<Model> Model
{
get
{
return _model;
}
set
{
if (_model != value)
{
_model = value;
RaisePropertyChanged(() => Model);
}
}
}
public ViewModel()
{
Model = new ObservableCollection<Model>();
}
}
这就是代码隐藏中的内容(可能不是完全这样):
public partial class UserControl1 : public UserControl
{
UserControl1( )
{
this.DataContext = new ViewModel( );
}
}
Xaml看起来像这样:
<DataGrid ItemsSource="{Binding Model}" />
我们的想法是,您的ViewModel准备用于演示的数据,整个演示文稿在Xaml(视图)中定义。使用"{Binding xxx}
“,您可以访问当前控件的'DataContext'
对象上的属性。因此,Xaml定义UserControl的子项,每个UserControl都有{{3}可以绑定UI(Xaml)上的对象。因此,您可以通过说ItemsSource="{Binding Model}"
<将DataGrid的DataContext(填充网格的项的源)绑定到DataContext的Model属性。 / p>