C# 理解MVVM:简单的非工作代码
我试图理解这个模式以及它背后的所有逻辑 我不认为这很难,但我仍然在一些简单的任务中失败了 让我们用我写的一个不起作用的例子来说明: 型号:C# 理解MVVM:简单的非工作代码,c#,xaml,mvvm,windows-phone-8,C#,Xaml,Mvvm,Windows Phone 8,我试图理解这个模式以及它背后的所有逻辑 我不认为这很难,但我仍然在一些简单的任务中失败了 让我们用我写的一个不起作用的例子来说明: 型号: public class Model { public string Name { get; set; } public string Description { get; set; } public Categories Category { get; set; } public Grid PresenterContent
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();
}
}
视图:
现在,当我运行它时,我希望它能够工作,因为我正在将DataContext
设置为ViewModel
,它有一个PresenterContent
属性
(此属性同时位于模型
和视图模型
中,因为我不知道如何使用子属性,在本例中为模型.PresenterContent
)
实际发生的情况是引发异常:
System.Windows.Data错误:BindingExpression路径错误:“ViewModel”“System.String”(HashCode=-903444198)上未找到PresenterContent属性。BindingExpression:Path='PresenterContent'DataItem='ViewModel'(HashCode=-903444198);目标元素是“System.Windows.Controls.ContentPresenter”(名称=“”);目标属性为“Content”(类型为“System.Object”)
这说明ViewModel
中没有PresenterContent
,这显然是错误的。
如果我尝试绑定到Model
属性,则例外情况相同
我做错了什么?问题是您正在将UserControl.DataContext绑定的源设置为字符串ViewModel,而不是ViewModel的实例(这就是为什么您的错误显示为“on'ViewModel''System.string') .
例如,要使其正常工作,您可以使用:
<UserControl.DataContext>
<vm:ViewModel/>
</UserControl.DataContext>
或者,您可以在App.xaml或视图资源中定义ViewModel,并在视图中使用:
<UserControl.DataContext>
<Binding Source="{StaticResource myViewModel}"/>
</UserControl.DataContext>
问题在于,您正在将UserControl.DataContext绑定的源设置为字符串ViewModel,而不是ViewModel的实例(这就是为什么您的错误为“on'ViewModel''System.string') .
例如,要使其正常工作,您可以使用:
<UserControl.DataContext>
<vm:ViewModel/>
</UserControl.DataContext>
或者,您可以在App.xaml或视图资源中定义ViewModel,并在视图中使用:
<UserControl.DataContext>
<Binding Source="{StaticResource myViewModel}"/>
</UserControl.DataContext>
您不应该在视图模型中放置用户控件(如网格);这就是美景。根据您的示例,您可能需要类似的控件,该控件在类似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>();
}
}
Xaml看起来是这样的:
public partial class UserControl1 : public UserControl
{
UserControl1( )
{
this.DataContext = new ViewModel( );
}
}
<DataGrid ItemsSource="{Binding Model}" />
其思想是您的ViewModel为表示准备数据,整个表示在Xaml(视图)中定义。使用
“{Binding xxx}
”可以访问当前控件的'DataContext'
对象的属性。所以Xaml定义了的子控件,每个UserControl都有一个可以绑定UI(Xaml)上的对象的子控件。因此,您可以通过说ItemsSource=“{Binding Model}”
将DataGrid(填充网格的项的源)绑定到DataContext的模型属性,您不应该在视图模型中放置UserControl(如grid);这就是美景。根据您的示例,您可能需要类似的控件,该控件在类似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>();
}
}
Xaml看起来是这样的:
public partial class UserControl1 : public UserControl
{
UserControl1( )
{
this.DataContext = new ViewModel( );
}
}
<DataGrid ItemsSource="{Binding Model}" />
其思想是您的ViewModel为表示准备数据,整个表示在Xaml(视图)中定义。使用
“{Binding xxx}
”可以访问当前控件的'DataContext'
对象的属性。所以Xaml定义了的子控件,每个UserControl都有一个可以绑定UI(Xaml)上的对象的子控件。因此,您可以通过说ItemsSource=“{Binding Model}”
都德,将DataGrid(填充网格的项的源)绑定到DataContext的模型属性。您不应该在模型中放置Grid
类型的属性。其思想是将用户界面和数据分开,而不是将它们更多地捆绑在一起。忘记类型,这只是一个示例。正如我所写,错误甚至出现在Model
属性中(甚至是我从代码中删除的字符串)。我认为您没有在usercontrol资源中添加ViewModel…在绑定中使用它之前,您需要将其添加为usercontrolresource@StepTNT即使这只是一个例子,您也应该听从HighCore的建议。这是MVVM的一个重要方面(基本的…事实上是驱动因素之一)。我不想假设太多。。。但是一个对MVVM设计目标有很好理解的人可能不会在VM中使用网格对象,即使在一个例子中也是如此。您不应该在模型中放置Grid
类型的属性。其思想是将用户界面和数据分开,而不是将它们更多地捆绑在一起。忘记类型,这只是一个示例。正如我所写,错误甚至出现在Model
属性中(甚至是我从代码中删除的字符串)。我认为您没有在usercontrol资源中添加ViewModel…在绑定中使用它之前,您需要将其添加为usercontrolresource@StepTNT即使这只是一个例子,您也应该听从HighCore的建议。这是MVVM的一个重要方面(基本的…事实上是驱动因素之一)。我不想假设太多。。。但是一个对MVVM设计目标有很好理解的人可能不会在VM中使用网格对象,即使是在一个示例中。