1

I read data from a database using sql-statements, which you can type in a textbox. When I run the query I want to add the returned data into different columns of the listview.

My code:

using (SqlConnection con = new SqlConnection(connectionString))
{
    con.Open();
    try
    {
        using (SqlCommand cmd = new SqlCommand(textBoxQuery.Text, con))
        {
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                GridView view = new GridView();
                string[] head = getColumnsName(textBoxQuery.Text);//Getting the columns names
                for (int i = 0; i != reader.FieldCount; i++)
                {
                      view.Columns.Add(new GridViewColumn() { Header = head[i] });//columns heading
                }
                listView.View = view;
                while (reader.Read())
                {
                     for (int i = 0; i != reader.FieldCount; i++)
                     {
                        //inserting data into one row and different columns
                     }
                     Console.WriteLine();
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
    con.Close();
}

Thanks in advance!

daniel59
  • 906
  • 2
  • 14
  • 31
  • Could use this to fill the listview from a Dictionary which you could create from the reader results, http://stackoverflow.com/a/11406299/2096538 – Daniel Wardin Nov 09 '15 at 10:47
  • no it's not possible because I use WPF and not winforms. In WPF the subitems don't exist. – daniel59 Nov 09 '15 at 10:56
  • Why do you do it programatically and not in the XAML file? – seeb Nov 09 '15 at 11:11
  • When I enter a new sql statement the column headings and the number of columns is changing, so I need to do it programmatically – daniel59 Nov 09 '15 at 11:19

1 Answers1

1

If you want the columns to generate dynamically for you in WPF you need to dynamically add column definitions with appropriate bindings each time you repopulate the list view.

Try this:

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace ListViewTest
{
    public class Column
    {
        public string Title { get; set; }
        public string SourceField { get; set; }
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            GridView gridView = new GridView();
            this.myListView.View = gridView;

            List<dynamic> myItems = new List<dynamic>();
            dynamic myItem;
            IDictionary<string, object> myItemValues;

            // Populate the objects with dynamic columns
            for (var i = 0; i < 100; i++)
            {
                myItem = new System.Dynamic.ExpandoObject();

                foreach (string column in new string[] { "Id", "Name", "Something" })
                {
                    myItemValues = (IDictionary<string, object>)myItem;
                    myItemValues[column] = "My value for " + column + " - " + i;
                }

                myItems.Add(myItem);
            }

            // Assuming that all objects have same columns - using first item to determine the columns
            List<Column> columns = new List<Column>();

            myItemValues = (IDictionary<string, object>)myItems[0];

            // Key is the column, value is the value
            foreach (var pair in myItemValues)
            {
                Column column = new Column();

                column.Title = pair.Key;
                column.SourceField = pair.Key;

                columns.Add(column);
            }

            // Add the column definitions to the list view
            gridView.Columns.Clear();

            foreach (var column in columns)
            {
                var binding = new Binding(column.SourceField);

                gridView.Columns.Add(new GridViewColumn { Header = column.Title, DisplayMemberBinding = binding });
            }

            // Add all items to the list
            foreach (dynamic item in myItems)
            {
                this.myListView.Items.Add(item);
            }
        }
    }
}

XAML:

<Window x:Class="ListViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListView x:Name="myListView"></ListView>
    </Grid>
</Window>

Only thing you need to change is adding columns from the reader by using the column name from sql query. And populating the ExpandoObject from fields returned by the reader from your query.

This is a quick demo I written up and didn't have access to a local database to test it so I mimicked it by the for loops and the string array.

Daniel Wardin
  • 1,840
  • 26
  • 48