【问题标题】:Understanding MVVM: simple non-working code理解 MVVM:简单的非工作代码
【发布时间】:2013-09-16 18:46:52
【问题描述】:

我正在尝试理解这种模式及其背后的所有逻辑。

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

让我们用我写的一个无效的例子来说明:

型号:

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 错误:BindingExpression 路径错误:在“ViewModel”“System.String”上找不到“PresenterContent”属性 (HashCode=-903444198)。 BindingExpression: Path='PresenterContent' DataItem='ViewModel' (HashCode=-903444198);目标元素是'System.Windows.Controls.ContentPresenter'(名称='');目标属性是“内容”(类型“System.Object”)..

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

我做错了什么?

【问题讨论】:

  • 老兄,你搞错了。您不应该在模型中放置Grid 类型的属性。这个想法是separate UI 和数据,而不是将它们更多地捆绑在一起。
  • 忘记类型,这只是一个例子。正如我所写,即使Model 属性(甚至是我从代码中删除的字符串)也会出现错误。
  • 我认为你还没有在你的用户控件资源中添加 ViewModel...在绑定中使用它之前你需要将它添加为用户控件资源
  • @StepTNT 即使这只是一个例子,你也应该听从 HighCore 的建议。这是 MVVM 的一个重要(基本......实际上是驱动因素之一)方面。我不想假设太多……但是对 MVVM 设计目标有深入了解的人可能不会在 VM 中使用 Grid 对象,即使在示例中也是如此。

标签: c# xaml mvvm windows-phone-8


【解决方案1】:

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

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

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

或者您可以在 App.xaml 或您的视图资源&lt;vm:ViewModel x:Key="myViewModel"/&gt; 中定义您的 ViewModel 并在您的视图中使用:

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

【讨论】:

    【解决方案2】:

    您不应该在视图模型中放置 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 都有一个DataContext,UI 上的对象指向哪些对象(Xaml) 可以绑定。因此您可以通过说 ItemsSource="{Binding Model}" 将 DataGrid 的 ItemsSource(填充网格的项目的源)绑定到 DataContext 的 Model 属性

    【讨论】:

      猜你喜欢
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 2018-10-04
      相关资源
      最近更新 更多