C# WPF:MVVM中的TreeView
我有一个C# WPF:MVVM中的TreeView,c#,wpf,xaml,mvvm,treeview,C#,Wpf,Xaml,Mvvm,Treeview,我有一个TreeView,我(终于)能够使用数据绑定从数据库中填充它 树中有两个对象: FavoriteFolder-可以有子对象的对象:文件夹或报表 FavoriteReport-不能有任何子对象的对象:当用户单击此项时,它将运行一个报告 目前,我有一个模型视图类型设置(我想),我想将其更改为MVVM,这样我就可以使用TreeView-项,而不是简单地显示它们 我已经看过很多例子,但我对MVVM和WPF还是比较陌生,所以对于我的具体例子的任何指导都将不胜感激 TreeView中存在的两个类
TreeView
,我(终于)能够使用数据绑定从数据库中填充它
树中有两个对象:
- FavoriteFolder-可以有子对象的对象:文件夹或报表
- FavoriteReport-不能有任何子对象的对象:当用户单击此项时,它将运行一个报告
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);
}
}
以及main window.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;
}
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
ObservableCollection items=新的ObservableCollection();
FavoriteFolder fdr=新的FavoriteFolder();
fdr.FolderID=“0”;
项目=fdr.儿童;
this.DataContext=项目;
}
}
我的第一个建议是加入一个MVVM工具包,因为它比自己做任何事情都要容易(例如,实现INotifyPropertyChanged
接口)。我用
假设您使用的是MVVM Light(如果您使用的是另一个工具包,则可以从中推断)
因此,要将其转换为MVVM,您需要做一些事情
模型
。我通常使用POCO,简单地定义模型的属性。这意味着要抽象出数据访问层(详见下文)视图模型
。在这里,您将在您的面纱中拥有您要绑定到的属性。您的可观察集合将位于此处。初始化您创建的类的实例将转到这里。对DAL层的调用将转到此处。(例如,而不是在视图的构造函数中)
将此ViewModel
添加到您的viewmodelocator
(我使用mvvmlight中提供的mvvmlocatorproperty
代码片段)
使用定位器将视图
绑定到视图模型
。在UserControl
中,您可以在声明中添加如下内容:
DataContext="{Binding YourViewModel, Source={StaticResource Locator}}"
ViewModelLocator
中,您需要新建(实例化)DAL服务类,并通过vm=newViewModel(MyDALService-dalService)
调用传递它。显然,您还需要在ViewModel
构造函数中接受MyDALService
引用。下面是我的EquipmentViewModel
构造器在我参与的项目中的一个示例:
public EquipmentViewModel(Services.IEquipmentService equipmentService)
{
EquipmentService = equipmentService;
LoadData();
}
ViewModel
接受IEquipmentService
类型的参数(这是我的界面)。在LoadData
方法中,我调用到达数据库层的DAL的EquipmentService.GetEquipment()
方法
任何问题都让我知道。MVVM可能是一种痛苦,但我很高兴我能坚持下去。
祝你好运 Josh Smith给出了关于如何使用的明确描述,我无法补充更多内容。我也不是设计专家,但将数据访问逻辑与模型分离不是很有意义吗?我同意,你认为创建一个单独的类来连接数据库,它有返回子元素的方法吗;模型。假设我有一个包含
Foo
集合的模型。现在我想将集合绑定到我的UI控件,那么,我必须在我的ViewModel中创建另一个集合,并使其与模型的集合保持同步?希望我遗漏了一些东西,因为我觉得这很可笑。为什么你会有一个只有Foo
集合的模型?创建一个名为Foo
(也称为Foo的单个实例,而不是集合)的模型,然后在视图模型中,在那里新建一个Foo
类的集合。显然,这就是一个示例。。。好的,我有一个带有id的模型,一个Foo集合,还有一个字符串名称。这有用吗?你的例子和我问的例子在语义上是不同的。你能想象一个包含集合类型的模型吗?它确实适用于任何类型。我看不出有一个模型和一个ViewModel的目的,它本质上模仿了所有这些属性,并为视图提供了PropertyChanged通知。就像我说的,我肯定错过了什么,因为那只是。。。哑巴,当然。。我有里面有收藏的模型。我实现了IEditableObject来处理模型上的更改跟踪。假设我在我的Bar
模型中有一组Foo
s。我在我的虚拟机中创建了一个条的集合(例如,可观察的集合条)。如果我有一个网格想要绑定到我的Foo
s,我只需要将它绑定到bar.Foo。我不会在视图模型中创建新的Foo集合。那将是荒谬和愚蠢的。是的,是的,它将是。因此,在本例中,您只需公开模型对象并绑定到它,因此它们需要发出属性更改通知,而不是VM本身。我想我根本不认为需要一个模型。我可以将所有这些数据都放在我的虚拟机中,并将UI绑定到它,虚拟机将是respo
public EquipmentViewModel(Services.IEquipmentService equipmentService)
{
EquipmentService = equipmentService;
LoadData();
}