簡體   English   中英

WPF:MVVM中的TreeView

[英]WPF: TreeView in MVVM

我有一個TreeView (最終),我可以使用數據綁定從數據庫中填充它。

樹中有2個對象:

  • FavoriteFolder-可以有子級的對象:文件夾或報表。
  • FavoriteReport —一個不能有子對象的對象:當用戶單擊此項目時,它將運行報告。

目前,我有一個Model-View類型設置(我認為),我想將其更改為MVVM,這樣我就可以使用TreeView -items進行操作,而不僅僅是顯示它們。

我看了很多示例,但是總體上我還是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接口)。 我使用Laurent Bungion的MVVM Light

假設您使用的是MVVM Light(如果使用其他工具包,則可以從中推斷)...

因此,要將其轉換為MVVM,您需要做一些事情。

  1. 創建定義的Models 我通常使用POCO,只需定義模型的屬性即可。 這意味着抽象出您的數據訪問層(更多內容請參見下文)。

  2. 創建您的ViewModel 在這里,您可以擁有自己要綁定的屬性。 您的ObservableCollections將坐在這里。 初始化您創建的類的實例將在此處進行。 調用您的DAL層將在此處進行。 (例如,而不是在視圖的構造函數中)。

    將此ViewModel添加到您的ViewModelLocator (我使用MVVM Light中提供的mvvmlocatorproperty代碼段)。

    使用LocatorView綁定到ViewModel 在您的UserControl ,您可以在聲明中添加以下內容:

     DataContext="{Binding YourViewModel, Source={StaticResource Locator}}" 
  3. 我會聽布倫南·文森特的建議。 我通常創建一個服務接口(注意:不是一個類,而是一個接口)來定義我的DAL(數據訪問層)將具有的方法。 我這樣做是為了考慮可混合性,也就是設計時間數據。 如果您不熟悉接口,那么也許簡單地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可能會很痛苦,但我很高興自己堅持了下來。 祝好運。 :)

Josh Smith對如何使用MVVM簡化TreeView作了明確的描述。我可以添加的內容不多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM