了解 MVVM:简单的非工作代码

本文关键字:工作 代码 简单 MVVM 了解 | 更新日期: 2023-09-27 18:31:34

>我试图理解这种模式及其背后的所有逻辑。

我不认为这很难,但我仍然在一些简单的任务中失败了。

让我们用我写的一个非工作示例来说明:

型:

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设置为具有PresenterContent属性的ViewModel

(此属性在ModelViewModel中,因为我不知道如何处理孩子的财产,在这种情况下Model.PresenterContent

实际发生的是抛出异常:

System.Windows.Data 错误:绑定表达式路径错误:"PresenterContent"属性在"ViewModel"System.String"(HashCode=-903444198)上找不到。BindingExpression: Path='PresenterContent' DataItem='ViewModel' (hashCode=-903444198);目标元素是"System.Windows.Controls.ContentPresenter"(Name='');目标属性是"内容"(类型"系统对象")。

这说明ViewModel中没有PresenterContent,这显然是错误的。如果我尝试绑定到Model属性,则异常是相同的。

我做错了什么?

了解 MVVM:简单的非工作代码

问题是你正在将UserControl.DataContext绑定的源设置为字符串ViewModel而不是ViewModel的实例(这就是为什么你的错误说"在'ViewModel''System.String'上

")

.
要使其工作,您可以例如使用:

<UserControl.DataContext>
    <vm:ViewModel/>
</UserControl.DataContext>

或者,您可以在 App.xaml 或视图资源<vm:ViewModel x:Key="myViewModel"/>中定义视图模型,并在视图中使用:

<UserControl.DataContext>
    <Binding Source="{StaticResource myViewModel}"/>
</UserControl.DataContext>

您不应该将用户控件(如 Grid)放在视图模型中;这就是视图的美妙之处。根据您的示例,您可能需要一个类似于 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 定义了用户控件的子项,并且每个用户控件都有一个 DataContext,UI (Xaml) 上的对象可以绑定到该上下文。因此,您可以通过说ItemsSource="{Binding Model}"