【问题标题】:WPF MVVM Pattern, ViewModel DataContext questionWPF MVVM 模式,ViewModel DataContext 问题
【发布时间】:2010-05-11 18:26:54
【问题描述】:

我使用这一面来创建我的演示应用程序 http://windowsclient.net/learn/video.aspx?v=314683

该站点对我的入门非常有用,在他们的示例中,他们创建了一个名为 EmployeeRepository.cs 的文件,该文件似乎是数据的来源。在他们的示例中,数据是硬连接在代码中的。所以我正在尝试学习如何从数据源(如数据库)获取数据。在我的具体情况下,我想从 Microsoft Access 数据库中获取数据。 (只读,所以我只会使用 SELECT 命令)。

using System.Collections.Generic;
using Telephone_Directory_2010.Model;

namespace Telephone_Directory_2010.DataAccess
{
    public class EmployeeRepository
    {
        readonly List<Employee> _employees;

        public EmployeeRepository()
        {
            if (_employees == null)
            {
                _employees = new List<Employee>();
            }
            _employees.Add(Employee.CreateEmployee("Student One", "IT201", "Information Technology", "IT4207", "Building1", "Room650"));
            _employees.Add(Employee.CreateEmployee("Student Two", "IT201", "Information Technology", "IT4207", "Building1", "Room650"));
            _employees.Add(Employee.CreateEmployee("Student Three", "IT201", "Information Technology", "IT4207", "Building1", "Room650"));
        }

        public List<Employee> GetEmployees()
        {
            return new List<Employee>(_employees);
        }
    }
}

我发现了另一个使用 Access DB 但不符合 MVVM 的示例。所以我试图弄清楚如何将数据库文件添加到项目中,如何连接它并将其绑定到列表框(我还没有那么远)。以下是我修改后的文件

using System.Collections.Generic;
using Telephone_Directory_2010.Model;
// integrating new code with working code
using Telephone_Directory_2010.telephone2010DataSetTableAdapters;
using System.Windows.Data;

namespace Telephone_Directory_2010.DataAccess
{
    public class EmployeeRepository
    {
        readonly List<Employee> _employees;

        // start
        // integrating new code with working code
        private telephone2010DataSet.telephone2010DataTable employeeTable;
        private CollectionView dataView;
        internal CollectionView DataView
        {
            get
            {
                if (dataView == null)
                {
                    dataView = (CollectionView) CollectionViewSource.GetDefaultView(this.DataContext);
                }
                return dataView;
            }
        }

        public EmployeeRepository()
        {
            if (_employees == null)
            {
                _employees = new List<Employee>();
            }
            telephone2010TableAdapter employeeTableAdapter = new telephone2010TableAdapter();
            employeeTable = employeeTableAdapter.GetData();
            this.DataContext = employeeTable;
        }

        public List<Employee> GetEmployees()
        {
            return new List<Employee>(_employees);
        }
    }

}

我在构建时收到以下错误消息

错误 1 ​​'Telephone_Directory_2010.DataAccess.EmployeeRepository' 不包含 'DataContext' 的定义并且没有扩展方法 'DataContext' 接受类型为 'Telephone_Directory_2010.DataAccess.EmployeeRepository' 的第一个参数(您是否缺少使用指令还是程序集参考?)C:\Projects\VS2010\Telephone Directory 2010\Telephone Directory 2010\DataAccess\EmployeeRepository.cs 23 90 Telephone Directory 2010

【问题讨论】:

  • 在我看来,您的问题与 MVVM 并不特别相关,而更多的是如何在 C# 中将数据访问层写入 Access 的问题?
  • 马蒂亚斯,你可能是对的。我对.Net 比较陌生。当 .Net 仍处于 1.0 阶段时,我做了一些 WinForms,然后我就不必使用它了。所以我熟悉 C# 和它的语法,但我完全不知道如何将我的数据从 Access DB 获取到我的 DataGrid(或 ListBox)。这是一个班级,我想真正学习如何正确地做它(而不是草率的代码来让它工作)
  • 从 C# 对 Jet/ACE 数据的数据访问不需要重新编写。但这个问题确实与 Access 无关。

标签: c# ms-access mvvm data-access-layer


【解决方案1】:

MVVM 模式应该建议三层:

Model (=Data-access):从数据库中检索数据,这里应该是您的 EmployeeRepository。我建议不要在这里使用任何特定于视图的组件,即没有 CollectionView。最好将您的员工放在 List 或 ObservableCollection 中。

ViewModel:在这里您可以为视图准备数据或实现命令,视图可以使用这些命令来检索或操作数据等。 在您的示例中,这应该是一些 EmployeeViewModel,它从 DataAccess-Layer 检索所有员工并将它们作为公共属性提供,以便视图可以绑定到它。不要在此处放置特定于数据库的代码,它应该完全包含在数据访问层中。

视图:您的员工视图,包含所有 UI 内容、按钮和所有这些。当然,您可以在此处放置一些 datagrid 或 ItemsControl,它们绑定到 ViewModel 并显示其数据。您的视图的数据上下文应该是您的 ViewModel,至少这是最常见的方式。

【讨论】:

  • 我的计划是从数据库中获取数据。然后为数据库中的每一行 foreach(employee in Table) { _employee.Add(employee.Name,employee.CourseNumber,employee.courseDepartment,employee.studentID,employee.Building,employee.RoomNumber)} 运行 for 循环只是伪代码,但想法是将其添加到 _employee 变量中。也许我走错了路,但后来我想通过文本框过滤我的结果进行搜索(所以我想找到一个名叫 Jason Borne 的学生或搜索所有参加 ENG101 课程的学生)。一个文本框2搜索所有列
  • 当然,您可以这样做,但是这样您将结合 Model (DB) 和 ViewModel(根据 MVVM),如果您不需要这种额外的抽象级别,这不一定是坏事。它也应该可以工作,但是您必须在正确的时间从视图中调用 GetEmployees() 方法。更优雅的是将您的员工放在 ObservableCollection 中(并使用属性“Employees”而不是方法“GetEmployees”),而不是您可以绑定到此属性并且不需要从视图触发刷新.
  • 如果我走那条路,我是否能够过滤我的数据而无需重新运行另一个 SQL 查询。现在我试图将数据放入我的 DataGrid(或 Listbox)。但后来我想添加一个“搜索框”,这样我就可以快速输入几个字母并从数据库中获取结果。
【解决方案2】:

我认为你需要研究几件事才能做你想做的事。

  1. WPF 工具包的 DataGridVIew - 不使用列表框来绑定数据,而是使用这个用于绑定数据集或数据表的数据网格。 DataGrid

  2. ADO.NET - Access 使用 OleDB 命名空间。您将需要创建与数据库的连接,并检索数据。您可以通过它填充绑定到数据网格的数据集。 OleDB

当你学会了这两个之后,你就可以坚持使用 MVVM,而且根据我自己的经验,学习这两个都是值得的。

【讨论】:

    猜你喜欢
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    • 2015-06-05
    • 1970-01-01
    • 2011-10-29
    相关资源
    最近更新 更多