vendredi 27 octobre 2017

how to bind checkboxes to a hierarchical treeview in WPF, using a MVVM design pattern

I would like to get some direction on how to bind checkboxe to each treeview's item (populated from an SQL DB) in such a way that when a stand-alone checkbox placed outside the treeview is ticked, all the treeview items containing, e.g: abc as the first three characters will be ticked. Following this, the selected threeview's items will be added into an array.

So far, I have a hierarchical Data template containing the treeview's items, as can be seen below. enter image description here

Below is the relevant code:

MainWindow.xaml

<Window x:Class="DB.MainWindow"
    xmlns="http://ift.tt/o66D3f"
    xmlns:x="http://ift.tt/mPTqtT"
    xmlns:d="http://ift.tt/pHvyf2"
    xmlns:mc="http://ift.tt/pzd6Lm"
    xmlns:local="clr-namespace:DB"
    mc:Ignorable="d"
    Title="DB" Height="350" Width="645.022"
      WindowStartupLocation="CenterScreen" Background="Gainsboro">
<Window.DataContext>
    <local:TreeViewModel></local:TreeViewModel>
</Window.DataContext>


<TreeView ItemsSource="{Binding Tree.Items}" Margin="0,0,421,0">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:DbViewModel}" ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center"/>
                <TextBlock Text="{Binding Name}"></TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView> </Window>

DBViewModel.cs

 public class DbViewModel 
{
    public DbViewModel()
    {
        Children = new ObservableCollection<DbViewModel>();
    }
    public string Id { get; set; }
    public string Name { get; set; }
    public ObservableCollection<DbViewModel> 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<DbViewModel>();
            var rootNode = new DbViewModel
            {
                Name = "Databases",
                Children = new ObservableCollection<DbViewModel>()
            };
            Items.Add(rootNode);

            IEnumerable<string> databases = GetNameList(databasesSchemaTable.Rows, 0);

            foreach (string dbName in databases)
            {
                var dbNode = new DbViewModel { 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 DbViewModel { Name = "Tables" };
                    dbNode.Children.Add(tableNode);
                    foreach (string tableName in tables)
                    {
                        tableNode.Children.Add(new DbViewModel { 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=**-PC\SQLSERVER2016;Database=DB_DEMO;" +
           "Integrated Security=true;";
    }

    public ObservableCollection<DbViewModel> Items { get; set; }
}
}

Thanks in advance for your help guys.




Aucun commentaire:

Enregistrer un commentaire