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

时间:2013-09-16 18:46:52

标签: 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 { 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属性。

(此属性同时位于ModelViewModel,因为我不知道使用子属性,在本例中为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属性,则异常相同。

我做错了什么?

2 个答案:

答案 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>