如何使用 MVVM 将数据库加载到 wpf 中的 TreeView
How to load database to TreeView in wpf with MVVM
using (DataConnectionDialog dlg = new DataConnectionDialog())
{
DataSource.AddStandardDataSources(dlg);
DataConnectionDialog.Show(dlg).ToString().Equals("OK");
DataProvider provider = dlg.SelectedDataProvider;
BcpConfig.DatabaseClient = provider.Name ;
string sqlDatabase = ConfigurationManager.AppSettings[provider.Name];
BcpConfig..Database = DatabaseFactory.CreateDb(dlg.ConnectionString, sqlDatabase);
上面是我的模型 class,它创建连接并给出连接字符串路径,如 "Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
这应该让你开始基于@sa_ddam213 answer here.
视图模型:
public class NodeViewModel
{
public NodeViewModel()
{
Children = new ObservableCollection<NodeViewModel>();
}
public string Id { get; set; }
public string Name { get; set; }
public ObservableCollection<NodeViewModel> Children { get; set; }
}
public class TreeViewModel
{
public TreeViewModel()
{
BuildTree();
}
public TreeViewModel Tree
{
get { return this; }
}
private void BuildTree()
{
string connectionString = GetConnectionString();
using (var connection = new SqlConnection(connectionString))
{
// Connect to the database then retrieve the schema information.
connection.Open();
// Get the schema information of Databases in your instance
DataTable databasesSchemaTable = connection.GetSchema("Databases");
Items = new ObservableCollection<NodeViewModel>();
var rootNode = new NodeViewModel
{
Name = "Databases",
Children = new ObservableCollection<NodeViewModel>()
};
Items.Add(rootNode);
IEnumerable<string> databases = GetNameList(databasesSchemaTable.Rows, 0);
foreach (string dbName in databases)
{
var dbNode = new NodeViewModel {Name = dbName};
rootNode.Children.Add(dbNode);
if (dbName.ToUpper().Equals("<yourdatabase>"))
{
DataTable table = connection.GetSchema("Tables");
IEnumerable<string> tables = GetNameList(table.Rows, 2);
var tableNode = new NodeViewModel {Name = "Tables"};
dbNode.Children.Add(tableNode);
foreach (string tableName in tables)
{
tableNode.Children.Add(new NodeViewModel {Name = tableName});
}
}
}
}
}
private IEnumerable<string> GetNameList(DataRowCollection drc, int index)
{
return drc.Cast<DataRow>().Select(r => r.ItemArray[index].ToString()).OrderBy(r => r).ToList();
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return @"Data Source=<yoursource>;Database=<yourdb>;" +
"Integrated Security=true;";
}
public ObservableCollection<NodeViewModel> Items { get; set; }
}
观点:
<Window x:Class="DBTree.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DBTree.ViewModel"
Title="MainWindow" Width="343" Height="744.625">
<Window.DataContext>
<local:TreeViewModel></local:TreeViewModel>
</Window.DataContext>
<TreeView ItemsSource="{Binding Tree.Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Window>
你会得到像这样非常简单的东西:
然后您可以添加样式、颜色、图标等
编辑: 我摆脱了视图代码隐藏并使用 TreeViewModel
作为 MainWindow
的 ViewModel
using (DataConnectionDialog dlg = new DataConnectionDialog())
{
DataSource.AddStandardDataSources(dlg);
DataConnectionDialog.Show(dlg).ToString().Equals("OK");
DataProvider provider = dlg.SelectedDataProvider;
BcpConfig.DatabaseClient = provider.Name ;
string sqlDatabase = ConfigurationManager.AppSettings[provider.Name];
BcpConfig..Database = DatabaseFactory.CreateDb(dlg.ConnectionString, sqlDatabase);
上面是我的模型 class,它创建连接并给出连接字符串路径,如 "Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
这应该让你开始基于@sa_ddam213 answer here.
视图模型:
public class NodeViewModel
{
public NodeViewModel()
{
Children = new ObservableCollection<NodeViewModel>();
}
public string Id { get; set; }
public string Name { get; set; }
public ObservableCollection<NodeViewModel> Children { get; set; }
}
public class TreeViewModel
{
public TreeViewModel()
{
BuildTree();
}
public TreeViewModel Tree
{
get { return this; }
}
private void BuildTree()
{
string connectionString = GetConnectionString();
using (var connection = new SqlConnection(connectionString))
{
// Connect to the database then retrieve the schema information.
connection.Open();
// Get the schema information of Databases in your instance
DataTable databasesSchemaTable = connection.GetSchema("Databases");
Items = new ObservableCollection<NodeViewModel>();
var rootNode = new NodeViewModel
{
Name = "Databases",
Children = new ObservableCollection<NodeViewModel>()
};
Items.Add(rootNode);
IEnumerable<string> databases = GetNameList(databasesSchemaTable.Rows, 0);
foreach (string dbName in databases)
{
var dbNode = new NodeViewModel {Name = dbName};
rootNode.Children.Add(dbNode);
if (dbName.ToUpper().Equals("<yourdatabase>"))
{
DataTable table = connection.GetSchema("Tables");
IEnumerable<string> tables = GetNameList(table.Rows, 2);
var tableNode = new NodeViewModel {Name = "Tables"};
dbNode.Children.Add(tableNode);
foreach (string tableName in tables)
{
tableNode.Children.Add(new NodeViewModel {Name = tableName});
}
}
}
}
}
private IEnumerable<string> GetNameList(DataRowCollection drc, int index)
{
return drc.Cast<DataRow>().Select(r => r.ItemArray[index].ToString()).OrderBy(r => r).ToList();
}
private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return @"Data Source=<yoursource>;Database=<yourdb>;" +
"Integrated Security=true;";
}
public ObservableCollection<NodeViewModel> Items { get; set; }
}
观点:
<Window x:Class="DBTree.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DBTree.ViewModel"
Title="MainWindow" Width="343" Height="744.625">
<Window.DataContext>
<local:TreeViewModel></local:TreeViewModel>
</Window.DataContext>
<TreeView ItemsSource="{Binding Tree.Items}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:NodeViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Window>
你会得到像这样非常简单的东西:
然后您可以添加样式、颜色、图标等
编辑: 我摆脱了视图代码隐藏并使用 TreeViewModel
作为 MainWindow