Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 理解MVVM:简单的非工作代码_C#_Xaml_Mvvm_Windows Phone 8 - Fatal编程技术网

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中使用网格对象,即使是在一个示例中。