1

I'm new in WPF and I'd like to visualize data from SQL query to WPF DataGrid. I have problem with a how correctly bind a data:

SqlCommand cmd = new SqlCommand(sql_dotaz, conn);
InfoText.Text += ("Příkaz vytvořen a připojen" + "\n");

try
{
    conn.Open();
    InfoText.Text += ("Připojení otevřeno" + "\n");

    SqlDataReader reader = cmd.ExecuteReader();

    int row_count = reader.FieldCount;  
    ArrayList propoj = new ArrayList();

    for (int i = 0; i < row_count; i++)
    {
        propoj.Add(reader.GetName(i));
        tabView.Columns.Add(new DataGridTextColumn 
            { 
                Header = reader.GetName(i), 
                Binding = new Binding(reader.GetName(i)) 
            });

        //Here is the problem!!!
        tabView.Items.Add(new {propoj[i] = "Hello"});
    }

Problem is when a try to add a new item, it's throws an error. I cannot explicitly set the header name like this (Invitation = "Hello").

I also tried

tabView.Columns.Add(new DataGridTextColumn 
    { 
        Header = reader.GetName(i), 
        Binding = new Binding(reader.GetName(i)) 
    });

string record = reader.GetName(i));
tabView.Items.Add(new {record = "Hello"});

But there is still a problem with the header name - The DataGrid is empty.

Please let me know if you have any ideas. Thanks a lot!

H.B.
  • 166,899
  • 29
  • 327
  • 400
VilemRousi
  • 2,082
  • 4
  • 24
  • 34
  • Hi Vilem, welcome to S.O and the wide world of WPF. As a couple users have indicated, while it's possible to add data directly to the DataGrid WPF Control, it's clumsy, error prone, and not the recommended method of making sure that your data is shown to the user. I support the recommendations that you look for examples on the `MVVM design pattern`, and familiarize yourself with `Data Binding` a `View` to a `ViewModel` – EtherDragon Jan 27 '12 at 17:16

5 Answers5

1

First of all, I don't think anonymous types will work in a binding. You'll somehow have to create a wrapper object for that:

// easiest case
public class DatabaseObject
{
    public List<string> Items = new List<string>();
}

With that, you can easily generate your columns:

// this should be renamed in something like columns or fieldCount...
int row_count = reader.FieldCount;  

for (int i = 0; i < row_count; i++)
{
    tabView.Columns.Add(new DataGridTextColumn 
        { 
            Header = reader.GetName(i), 
            Binding = new Binding("Items[i]") 
        });
}

And fill your DataGrid:

if(reader.HasRows)
{
    do
    {
        DatabaseObject obj = new DatabaseObject();
        for (int i = 0; i < row_count; i++)
        {
            obj.Items.Add(reader.GetString(i));
        }

        tabView.Items.Add(obj);
    }
    while(reader.NextResult());
}
Nuffin
  • 3,882
  • 18
  • 34
0

You need to manage this with DataBinding, as you specified WPF like technology in tags.

Example links :

Link1

Link 2

Link 3

Community
  • 1
  • 1
Tigran
  • 61,654
  • 8
  • 86
  • 123
0

if wanna go the easy way:

  1. fill a datatable with your data.
  2. simply bind the itemssource from the datagrid to your datatable. (Read about DataBinding and MVVM)

    <DataGrid ItemsSource="{Binding MyFilledDataTableProperty}" />

  3. set the right datacontext.

blindmeis
  • 22,175
  • 7
  • 55
  • 74
0

In the I find the solution. Maybe it´s not best but it´s work. I create DataSet and SQL Adapter

adapter.Fill(dSet);
this.DataContext = dSet.Tables[0].DefaultView;

and in XAML:

<DataGrid Height="Auto" Width="Auto" Name="tabView3" ItemsSource="{Binding}" />

And now it´s work fine :-)

VilemRousi
  • 2,082
  • 4
  • 24
  • 34
-1

This is what worked for me:

IN THE XAML FILE:

    <DataGrid Name="YourDataGrid"  CanUserAddRows="true" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected" Width="auto" SelectionUnit="FullRow" RowEditEnding="YourDataGrid_RowEditEnding" AddingNewItem="YourDataGrid_AddingNewItem">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="VideoID_column" Binding="{Binding IDVideo, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Video ID" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="VideoTitle_column" Binding="{Binding Titlu,NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Title" Width="auto"/>
            </DataGrid.Columns>
        </DataGrid>

IN THE .CS File

        private void YourDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        if (e.EditAction == DataGridEditAction.Commit && isInsertMode == true)
        {
            var vid = e.Row.DataContext as video;

            var context = new YourEntities();
            var Video = new video //video is the class
            {

                IDVideo = vid.IDVideo,
                Titlu = vid.Titlu
            };
            context.videos.Add(Video);
            context.SaveChanges();
        }
    }

    private void YourDataGrid_AddingNewItem(object sender, AddingNewItemEventArgs e)
    {
        isInsertMode = true;
    }

Hope that helps!