c# – WPF:MVVM中的TreeView

我有一个TreeView,我(最终)能够使用数据绑定从数据库填充.

树中有两个对象:

> FavoriteFolder – 可以有子项的对象:文件夹或报告.
> FavoriteReport – 一个不能有任何子节点的对象:当用户点击此项时,它将运行一个报表.

目前我有一个模型 – 视图类型设置(我认为),我想将其更改为MVVM,以便我可以使用TreeView项目而不是简单地显示它们.

我已经看了很多例子,但我仍然是MVVM和WPF的新手,所以对我的特定例子的任何指导都会非常感激

我在TreeView中存在的两个类是:

文件夹项目:

public class FavoriteFolder
{
    private string _connectionString = new ServerInfo().ConnectionString;
    private string _folderID;
    private string _parentID;
    private string _folderTitle;

    private ObservableCollection<FavoriteFolder> _folders;
    private ObservableCollection<FavoriteReport> _reports;
    private ObservableCollection<object> _children;

    public FavoriteFolder()
    {

    }

    public ObservableCollection<object> Children
    {
        get 
        {
            _getChildren();
            return _children; 
        }
    }

    public string FolderID
    {
        get { return _folderID; }
        set { _folderID = value; }
    }

    public string ParentID
    {
        get { return _parentID; }
        set { _parentID = value; }
    }

    public string FolderTitle
    {
        get { return _folderTitle; }
        set { _folderTitle = value; }
    }

    private void _getChildren()
    {
        _folders = new ObservableCollection<FavoriteFolder>();
        _reports = new ObservableCollection<FavoriteReport>();

        using (SqlConnection cnn = new SqlConnection(_connectionString))
        {
            cnn.Open();
            string sql = "SELECT * FROM tbl_report_folders where fdr_parent_id =" + _folderID;
            SqlCommand cmd = new SqlCommand(sql, cnn);

            SqlDataReader reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                FavoriteFolder folder = new FavoriteFolder();

                folder.FolderID = reader["fdr_folder_id"].ToString();
                folder.FolderTitle = reader["fdr_folder_name"].ToString();
                folder.ParentID = reader["fdr_parent_id"].ToString();

                _folders.Add(folder);
            }

            reader.Close();

            sql = "SELECT * FROM tbl_reports where rpt_folder_id =" + _folderID;
            cmd = new SqlCommand(sql, cnn);

            reader = cmd.ExecuteReader();

            while (reader.Read())
            {
                FavoriteReport report = new FavoriteReport();

                report.ReportID = reader["rpt_report_id"].ToString();
                report.ReportTitle = reader["rpt_report_name"].ToString();
                report.ParentID = reader["rpt_folder_id"].ToString();

                _reports.Add(report);
            }
        }

        //add the children to the collection
        foreach (var folder in this._folders)
            _children.Add(folder);

        foreach (var report in this._reports)
            _children.Add(report);
    }
}

报告项目:

public class FavoriteReport
{
    private string _reportID;
    private string _parentID;
    private string _reportTitle;

    public FavoriteReport()
    {

    }

    public string ReportID
    {
        get { return _reportID; }
        set { _reportID = value; }
    }

    public string ParentID
    {
        get { return _parentID; }
        set { _parentID = value; }
    }

    public string ReportTitle
    {
        get { return _reportTitle; }
        set { _reportTitle = value; }
    }
}

和MainWindow.xaml.cs –

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        ObservableCollection<object> items = new ObservableCollection<object>();

        FavoriteFolder fdr = new FavoriteFolder();

        fdr.FolderID = "0";

        items = fdr.Children;

        this.DataContext = items;
    }
}

解决方法:

我的第一个建议是放入MVVM工具包,因为它比自己做所有事情更容易(例如实现INotifyPropertyChanged接口).我用MVVM Light by Laurent Bungion.

假设您正在使用MVVM Light(如果您正在使用其他工具包,则可以从此推断)…

因此,要将其转换为MVVM,您需要做一些事情.

>创建定义的模型.我通常使用POCO,只是定义模型的属性.这意味着抽象出您的数据访问层(详见下文).
>创建您的ViewModel.这就是您在自己的视野中拥有属性的地方.你的ObservableCollections会坐在这里.初始化您创建的类的实例将在此处.对您的DAL图层的调用将在此处进行. (例如,而不是在视图的构造函数中).

将此ViewModel添加到ViewModelLocator(我使用MVVM Light中提供的mvvmlocatorproperty代码段).

使用定位器将View绑定到ViewModel.在你的UserControl中,你会在声明中添加这样的东西:

DataContext="{Binding YourViewModel, Source={StaticResource Locator}}"

>我会按照Brennan Vincent的建议.我通常创建一个服务接口(注意:不是类,而是接口),它定义了我的DAL(数据访问层)将具有的方法.我这样做是为了允许Blendability,即设计时数据.如果你不熟悉接口,也许只是一个DAL类是一个很好的开始.然后我使用依赖注入(DI)来注入我的DAL服务的实例. DI非常简单 – 在ViewModelLocator中,您需要新建(实例化)您的DAL服务类&通过你的vm = New ViewModel(MyDALService dalService)调用传递它.显然,您还需要在ViewModel构造函数中接受MyDALService引用.这是我工作的项目上的EquipmentViewModel构造函数的示例:

public EquipmentViewModel(Services.IEquipmentService equipmentService)
{
    EquipmentService = equipmentService;
    LoadData();
}

此ViewModel接受IEquipmentService类型的参数(这是我的接口).在LoadData方法中,我调用DAL的EquipmentService.GetEquipment()方法,该方法命中我的数据库层.

有任何问题让我知道. MVVM可能很痛苦,但我很高兴我坚持下去.
祝好运.

上一篇:c# – 双击TreeNode复选框上的beavior


下一篇:c# – 如何防止我的WPF TreeView聚焦所选的TreeViewItem